Lines Matching +full:xo +full:- +full:1
2 * xfrm_replay.c - xfrm replay detection, derived from xfrm_state.c.
18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
27 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_seqhi()
29 if (!(x->props.flags & XFRM_STATE_ESN)) in xfrm_replay_seqhi()
33 seq_hi = replay_esn->seq_hi; in xfrm_replay_seqhi()
34 bottom = replay_esn->seq - replay_esn->replay_window + 1; in xfrm_replay_seqhi()
36 if (likely(replay_esn->seq >= replay_esn->replay_window - 1)) { in xfrm_replay_seqhi()
43 seq_hi--; in xfrm_replay_seqhi()
54 * 1. we updated on of the sequence numbers, and the seqno difference in xfrm_replay_notify()
55 * is at least x->replay_maxdiff, in this case we also update the in xfrm_replay_notify()
57 * 2. if x->replay_maxage has elapsed since last update, in xfrm_replay_notify()
65 if (!x->replay_maxdiff || in xfrm_replay_notify()
66 ((x->replay.seq - x->preplay.seq < x->replay_maxdiff) && in xfrm_replay_notify()
67 (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff))) { in xfrm_replay_notify()
68 if (x->xflags & XFRM_TIME_DEFER) in xfrm_replay_notify()
77 if (memcmp(&x->replay, &x->preplay, in xfrm_replay_notify()
79 x->xflags |= XFRM_TIME_DEFER; in xfrm_replay_notify()
86 memcpy(&x->preplay, &x->replay, sizeof(struct xfrm_replay_state)); in xfrm_replay_notify()
91 if (x->replay_maxage && in xfrm_replay_notify()
92 !mod_timer(&x->rtimer, jiffies + x->replay_maxage)) in xfrm_replay_notify()
93 x->xflags &= ~XFRM_TIME_DEFER; in xfrm_replay_notify()
101 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { in xfrm_replay_overflow()
102 XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq; in xfrm_replay_overflow()
103 XFRM_SKB_CB(skb)->seq.output.hi = 0; in xfrm_replay_overflow()
104 if (unlikely(x->replay.oseq == 0)) { in xfrm_replay_overflow()
105 x->replay.oseq--; in xfrm_replay_overflow()
107 err = -EOVERFLOW; in xfrm_replay_overflow()
112 x->repl->notify(x, XFRM_REPLAY_UPDATE); in xfrm_replay_overflow()
124 if (!x->props.replay_window) in xfrm_replay_check()
130 if (likely(seq > x->replay.seq)) in xfrm_replay_check()
133 diff = x->replay.seq - seq; in xfrm_replay_check()
134 if (diff >= x->props.replay_window) { in xfrm_replay_check()
135 x->stats.replay_window++; in xfrm_replay_check()
139 if (x->replay.bitmap & (1U << diff)) { in xfrm_replay_check()
140 x->stats.replay++; in xfrm_replay_check()
147 return -EINVAL; in xfrm_replay_check()
155 if (!x->props.replay_window) in xfrm_replay_advance()
158 if (seq > x->replay.seq) { in xfrm_replay_advance()
159 diff = seq - x->replay.seq; in xfrm_replay_advance()
160 if (diff < x->props.replay_window) in xfrm_replay_advance()
161 x->replay.bitmap = ((x->replay.bitmap) << diff) | 1; in xfrm_replay_advance()
163 x->replay.bitmap = 1; in xfrm_replay_advance()
164 x->replay.seq = seq; in xfrm_replay_advance()
166 diff = x->replay.seq - seq; in xfrm_replay_advance()
167 x->replay.bitmap |= (1U << diff); in xfrm_replay_advance()
171 x->repl->notify(x, XFRM_REPLAY_UPDATE); in xfrm_replay_advance()
177 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_overflow_bmp()
180 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { in xfrm_replay_overflow_bmp()
181 XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq; in xfrm_replay_overflow_bmp()
182 XFRM_SKB_CB(skb)->seq.output.hi = 0; in xfrm_replay_overflow_bmp()
183 if (unlikely(replay_esn->oseq == 0)) { in xfrm_replay_overflow_bmp()
184 replay_esn->oseq--; in xfrm_replay_overflow_bmp()
186 err = -EOVERFLOW; in xfrm_replay_overflow_bmp()
191 x->repl->notify(x, XFRM_REPLAY_UPDATE); in xfrm_replay_overflow_bmp()
201 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_check_bmp()
204 u32 diff = replay_esn->seq - seq; in xfrm_replay_check_bmp()
206 if (!replay_esn->replay_window) in xfrm_replay_check_bmp()
212 if (likely(seq > replay_esn->seq)) in xfrm_replay_check_bmp()
215 if (diff >= replay_esn->replay_window) { in xfrm_replay_check_bmp()
216 x->stats.replay_window++; in xfrm_replay_check_bmp()
220 pos = (replay_esn->seq - 1) % replay_esn->replay_window; in xfrm_replay_check_bmp()
223 bitnr = (pos - diff) % replay_esn->replay_window; in xfrm_replay_check_bmp()
225 bitnr = replay_esn->replay_window - (diff - pos); in xfrm_replay_check_bmp()
229 if (replay_esn->bmp[nr] & (1U << bitnr)) in xfrm_replay_check_bmp()
235 x->stats.replay++; in xfrm_replay_check_bmp()
238 return -EINVAL; in xfrm_replay_check_bmp()
245 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_advance_bmp()
249 if (!replay_esn->replay_window) in xfrm_replay_advance_bmp()
252 pos = (replay_esn->seq - 1) % replay_esn->replay_window; in xfrm_replay_advance_bmp()
254 if (seq > replay_esn->seq) { in xfrm_replay_advance_bmp()
255 diff = seq - replay_esn->seq; in xfrm_replay_advance_bmp()
257 if (diff < replay_esn->replay_window) { in xfrm_replay_advance_bmp()
258 for (i = 1; i < diff; i++) { in xfrm_replay_advance_bmp()
259 bitnr = (pos + i) % replay_esn->replay_window; in xfrm_replay_advance_bmp()
262 replay_esn->bmp[nr] &= ~(1U << bitnr); in xfrm_replay_advance_bmp()
265 nr = (replay_esn->replay_window - 1) >> 5; in xfrm_replay_advance_bmp()
267 replay_esn->bmp[i] = 0; in xfrm_replay_advance_bmp()
270 bitnr = (pos + diff) % replay_esn->replay_window; in xfrm_replay_advance_bmp()
271 replay_esn->seq = seq; in xfrm_replay_advance_bmp()
273 diff = replay_esn->seq - seq; in xfrm_replay_advance_bmp()
276 bitnr = (pos - diff) % replay_esn->replay_window; in xfrm_replay_advance_bmp()
278 bitnr = replay_esn->replay_window - (diff - pos); in xfrm_replay_advance_bmp()
283 replay_esn->bmp[nr] |= (1U << bitnr); in xfrm_replay_advance_bmp()
286 x->repl->notify(x, XFRM_REPLAY_UPDATE); in xfrm_replay_advance_bmp()
292 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_notify_bmp()
293 struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn; in xfrm_replay_notify_bmp()
296 * 1. we updated on of the sequence numbers, and the seqno difference in xfrm_replay_notify_bmp()
297 * is at least x->replay_maxdiff, in this case we also update the in xfrm_replay_notify_bmp()
299 * 2. if x->replay_maxage has elapsed since last update, in xfrm_replay_notify_bmp()
307 if (!x->replay_maxdiff || in xfrm_replay_notify_bmp()
308 ((replay_esn->seq - preplay_esn->seq < x->replay_maxdiff) && in xfrm_replay_notify_bmp()
309 (replay_esn->oseq - preplay_esn->oseq in xfrm_replay_notify_bmp()
310 < x->replay_maxdiff))) { in xfrm_replay_notify_bmp()
311 if (x->xflags & XFRM_TIME_DEFER) in xfrm_replay_notify_bmp()
320 if (memcmp(x->replay_esn, x->preplay_esn, in xfrm_replay_notify_bmp()
322 x->xflags |= XFRM_TIME_DEFER; in xfrm_replay_notify_bmp()
329 memcpy(x->preplay_esn, x->replay_esn, in xfrm_replay_notify_bmp()
335 if (x->replay_maxage && in xfrm_replay_notify_bmp()
336 !mod_timer(&x->rtimer, jiffies + x->replay_maxage)) in xfrm_replay_notify_bmp()
337 x->xflags &= ~XFRM_TIME_DEFER; in xfrm_replay_notify_bmp()
344 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_notify_esn()
345 struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn; in xfrm_replay_notify_esn()
348 * 1. we updated on of the sequence numbers, and the seqno difference in xfrm_replay_notify_esn()
349 * is at least x->replay_maxdiff, in this case we also update the in xfrm_replay_notify_esn()
351 * 2. if x->replay_maxage has elapsed since last update, in xfrm_replay_notify_esn()
359 if (x->replay_maxdiff) { in xfrm_replay_notify_esn()
360 if (replay_esn->seq_hi == preplay_esn->seq_hi) in xfrm_replay_notify_esn()
361 seq_diff = replay_esn->seq - preplay_esn->seq; in xfrm_replay_notify_esn()
363 seq_diff = ~preplay_esn->seq + replay_esn->seq in xfrm_replay_notify_esn()
364 + 1; in xfrm_replay_notify_esn()
366 if (replay_esn->oseq_hi == preplay_esn->oseq_hi) in xfrm_replay_notify_esn()
367 oseq_diff = replay_esn->oseq in xfrm_replay_notify_esn()
368 - preplay_esn->oseq; in xfrm_replay_notify_esn()
370 oseq_diff = ~preplay_esn->oseq in xfrm_replay_notify_esn()
371 + replay_esn->oseq + 1; in xfrm_replay_notify_esn()
373 if (seq_diff >= x->replay_maxdiff || in xfrm_replay_notify_esn()
374 oseq_diff >= x->replay_maxdiff) in xfrm_replay_notify_esn()
378 if (x->xflags & XFRM_TIME_DEFER) in xfrm_replay_notify_esn()
386 if (memcmp(x->replay_esn, x->preplay_esn, in xfrm_replay_notify_esn()
388 x->xflags |= XFRM_TIME_DEFER; in xfrm_replay_notify_esn()
395 memcpy(x->preplay_esn, x->replay_esn, in xfrm_replay_notify_esn()
401 if (x->replay_maxage && in xfrm_replay_notify_esn()
402 !mod_timer(&x->rtimer, jiffies + x->replay_maxage)) in xfrm_replay_notify_esn()
403 x->xflags &= ~XFRM_TIME_DEFER; in xfrm_replay_notify_esn()
409 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_overflow_esn()
412 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { in xfrm_replay_overflow_esn()
413 XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq; in xfrm_replay_overflow_esn()
414 XFRM_SKB_CB(skb)->seq.output.hi = replay_esn->oseq_hi; in xfrm_replay_overflow_esn()
416 if (unlikely(replay_esn->oseq == 0)) { in xfrm_replay_overflow_esn()
417 XFRM_SKB_CB(skb)->seq.output.hi = ++replay_esn->oseq_hi; in xfrm_replay_overflow_esn()
419 if (replay_esn->oseq_hi == 0) { in xfrm_replay_overflow_esn()
420 replay_esn->oseq--; in xfrm_replay_overflow_esn()
421 replay_esn->oseq_hi--; in xfrm_replay_overflow_esn()
423 err = -EOVERFLOW; in xfrm_replay_overflow_esn()
429 x->repl->notify(x, XFRM_REPLAY_UPDATE); in xfrm_replay_overflow_esn()
440 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_check_esn()
443 u32 wsize = replay_esn->replay_window; in xfrm_replay_check_esn()
444 u32 top = replay_esn->seq; in xfrm_replay_check_esn()
445 u32 bottom = top - wsize + 1; in xfrm_replay_check_esn()
450 if (unlikely(seq == 0 && replay_esn->seq_hi == 0 && in xfrm_replay_check_esn()
451 (replay_esn->seq < replay_esn->replay_window - 1))) in xfrm_replay_check_esn()
454 diff = top - seq; in xfrm_replay_check_esn()
456 if (likely(top >= wsize - 1)) { in xfrm_replay_check_esn()
465 diff = ~seq + top + 1; in xfrm_replay_check_esn()
468 if (diff >= replay_esn->replay_window) { in xfrm_replay_check_esn()
469 x->stats.replay_window++; in xfrm_replay_check_esn()
473 pos = (replay_esn->seq - 1) % replay_esn->replay_window; in xfrm_replay_check_esn()
476 bitnr = (pos - diff) % replay_esn->replay_window; in xfrm_replay_check_esn()
478 bitnr = replay_esn->replay_window - (diff - pos); in xfrm_replay_check_esn()
482 if (replay_esn->bmp[nr] & (1U << bitnr)) in xfrm_replay_check_esn()
488 x->stats.replay++; in xfrm_replay_check_esn()
491 return -EINVAL; in xfrm_replay_check_esn()
497 if (unlikely(XFRM_SKB_CB(skb)->seq.input.hi != in xfrm_replay_recheck_esn()
499 x->stats.replay_window++; in xfrm_replay_recheck_esn()
500 return -EINVAL; in xfrm_replay_recheck_esn()
511 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_advance_esn()
513 if (!replay_esn->replay_window) in xfrm_replay_advance_esn()
517 pos = (replay_esn->seq - 1) % replay_esn->replay_window; in xfrm_replay_advance_esn()
519 wrap = seq_hi - replay_esn->seq_hi; in xfrm_replay_advance_esn()
521 if ((!wrap && seq > replay_esn->seq) || wrap > 0) { in xfrm_replay_advance_esn()
523 diff = seq - replay_esn->seq; in xfrm_replay_advance_esn()
525 diff = ~replay_esn->seq + seq + 1; in xfrm_replay_advance_esn()
527 if (diff < replay_esn->replay_window) { in xfrm_replay_advance_esn()
528 for (i = 1; i < diff; i++) { in xfrm_replay_advance_esn()
529 bitnr = (pos + i) % replay_esn->replay_window; in xfrm_replay_advance_esn()
532 replay_esn->bmp[nr] &= ~(1U << bitnr); in xfrm_replay_advance_esn()
535 nr = (replay_esn->replay_window - 1) >> 5; in xfrm_replay_advance_esn()
537 replay_esn->bmp[i] = 0; in xfrm_replay_advance_esn()
540 bitnr = (pos + diff) % replay_esn->replay_window; in xfrm_replay_advance_esn()
541 replay_esn->seq = seq; in xfrm_replay_advance_esn()
544 replay_esn->seq_hi++; in xfrm_replay_advance_esn()
546 diff = replay_esn->seq - seq; in xfrm_replay_advance_esn()
549 bitnr = (pos - diff) % replay_esn->replay_window; in xfrm_replay_advance_esn()
551 bitnr = replay_esn->replay_window - (diff - pos); in xfrm_replay_advance_esn()
558 replay_esn->bmp[nr] |= (1U << bitnr); in xfrm_replay_advance_esn()
561 x->repl->notify(x, XFRM_REPLAY_UPDATE); in xfrm_replay_advance_esn()
569 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm_replay_overflow_offload() local
570 __u32 oseq = x->replay.oseq; in xfrm_replay_overflow_offload()
572 if (!xo) in xfrm_replay_overflow_offload()
575 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { in xfrm_replay_overflow_offload()
577 XFRM_SKB_CB(skb)->seq.output.low = ++oseq; in xfrm_replay_overflow_offload()
578 xo->seq.low = oseq; in xfrm_replay_overflow_offload()
580 XFRM_SKB_CB(skb)->seq.output.low = oseq + 1; in xfrm_replay_overflow_offload()
581 xo->seq.low = oseq + 1; in xfrm_replay_overflow_offload()
582 oseq += skb_shinfo(skb)->gso_segs; in xfrm_replay_overflow_offload()
585 XFRM_SKB_CB(skb)->seq.output.hi = 0; in xfrm_replay_overflow_offload()
586 xo->seq.hi = 0; in xfrm_replay_overflow_offload()
587 if (unlikely(oseq < x->replay.oseq)) { in xfrm_replay_overflow_offload()
589 err = -EOVERFLOW; in xfrm_replay_overflow_offload()
594 x->replay.oseq = oseq; in xfrm_replay_overflow_offload()
597 x->repl->notify(x, XFRM_REPLAY_UPDATE); in xfrm_replay_overflow_offload()
606 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm_replay_overflow_offload_bmp() local
607 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_overflow_offload_bmp()
609 __u32 oseq = replay_esn->oseq; in xfrm_replay_overflow_offload_bmp()
611 if (!xo) in xfrm_replay_overflow_offload_bmp()
614 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { in xfrm_replay_overflow_offload_bmp()
616 XFRM_SKB_CB(skb)->seq.output.low = ++oseq; in xfrm_replay_overflow_offload_bmp()
617 xo->seq.low = oseq; in xfrm_replay_overflow_offload_bmp()
619 XFRM_SKB_CB(skb)->seq.output.low = oseq + 1; in xfrm_replay_overflow_offload_bmp()
620 xo->seq.low = oseq + 1; in xfrm_replay_overflow_offload_bmp()
621 oseq += skb_shinfo(skb)->gso_segs; in xfrm_replay_overflow_offload_bmp()
624 XFRM_SKB_CB(skb)->seq.output.hi = 0; in xfrm_replay_overflow_offload_bmp()
625 xo->seq.hi = 0; in xfrm_replay_overflow_offload_bmp()
626 if (unlikely(oseq < replay_esn->oseq)) { in xfrm_replay_overflow_offload_bmp()
628 err = -EOVERFLOW; in xfrm_replay_overflow_offload_bmp()
632 replay_esn->oseq = oseq; in xfrm_replay_overflow_offload_bmp()
636 x->repl->notify(x, XFRM_REPLAY_UPDATE); in xfrm_replay_overflow_offload_bmp()
645 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm_replay_overflow_offload_esn() local
646 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_replay_overflow_offload_esn()
648 __u32 oseq = replay_esn->oseq; in xfrm_replay_overflow_offload_esn()
649 __u32 oseq_hi = replay_esn->oseq_hi; in xfrm_replay_overflow_offload_esn()
651 if (!xo) in xfrm_replay_overflow_offload_esn()
654 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { in xfrm_replay_overflow_offload_esn()
656 XFRM_SKB_CB(skb)->seq.output.low = ++oseq; in xfrm_replay_overflow_offload_esn()
657 XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi; in xfrm_replay_overflow_offload_esn()
658 xo->seq.low = oseq; in xfrm_replay_overflow_offload_esn()
659 xo->seq.hi = oseq_hi; in xfrm_replay_overflow_offload_esn()
661 XFRM_SKB_CB(skb)->seq.output.low = oseq + 1; in xfrm_replay_overflow_offload_esn()
662 XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi; in xfrm_replay_overflow_offload_esn()
663 xo->seq.low = oseq + 1; in xfrm_replay_overflow_offload_esn()
664 xo->seq.hi = oseq_hi; in xfrm_replay_overflow_offload_esn()
665 oseq += skb_shinfo(skb)->gso_segs; in xfrm_replay_overflow_offload_esn()
668 if (unlikely(oseq < replay_esn->oseq)) { in xfrm_replay_overflow_offload_esn()
669 XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi; in xfrm_replay_overflow_offload_esn()
670 xo->seq.hi = oseq_hi; in xfrm_replay_overflow_offload_esn()
671 replay_esn->oseq_hi = oseq_hi; in xfrm_replay_overflow_offload_esn()
672 if (replay_esn->oseq_hi == 0) { in xfrm_replay_overflow_offload_esn()
673 replay_esn->oseq--; in xfrm_replay_overflow_offload_esn()
674 replay_esn->oseq_hi--; in xfrm_replay_overflow_offload_esn()
676 err = -EOVERFLOW; in xfrm_replay_overflow_offload_esn()
682 replay_esn->oseq = oseq; in xfrm_replay_overflow_offload_esn()
685 x->repl->notify(x, XFRM_REPLAY_UPDATE); in xfrm_replay_overflow_offload_esn()
742 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; in xfrm_init_replay()
745 if (replay_esn->replay_window > in xfrm_init_replay()
746 replay_esn->bmp_len * sizeof(__u32) * 8) in xfrm_init_replay()
747 return -EINVAL; in xfrm_init_replay()
749 if (x->props.flags & XFRM_STATE_ESN) { in xfrm_init_replay()
750 if (replay_esn->replay_window == 0) in xfrm_init_replay()
751 return -EINVAL; in xfrm_init_replay()
752 x->repl = &xfrm_replay_esn; in xfrm_init_replay()
754 x->repl = &xfrm_replay_bmp; in xfrm_init_replay()
757 x->repl = &xfrm_replay_legacy; in xfrm_init_replay()