* Check replay counter whether to update or not. * OUT: 0: OK * 1: NG */
| 1361 | * 1: NG |
| 1362 | */ |
| 1363 | int |
| 1364 | ipsec_updatereplay(uint32_t seq, struct secasvar *sav) |
| 1365 | { |
| 1366 | struct secreplay *replay; |
| 1367 | uint32_t window; |
| 1368 | uint32_t tl, th, bl; |
| 1369 | uint32_t seqh; |
| 1370 | |
| 1371 | IPSEC_ASSERT(sav != NULL, ("Null SA")); |
| 1372 | IPSEC_ASSERT(sav->replay != NULL, ("Null replay state")); |
| 1373 | |
| 1374 | replay = sav->replay; |
| 1375 | |
| 1376 | /* No need to check replay if disabled. */ |
| 1377 | if (replay->wsize == 0) |
| 1378 | return (0); |
| 1379 | |
| 1380 | /* Zero sequence number is not allowed. */ |
| 1381 | if (seq == 0 && replay->last == 0) |
| 1382 | return (1); |
| 1383 | |
| 1384 | window = replay->wsize << 3; /* Size of window */ |
| 1385 | tl = (uint32_t)replay->last; /* Top of window, lower part */ |
| 1386 | th = (uint32_t)(replay->last >> 32); /* Top of window, high part */ |
| 1387 | bl = tl - window + 1; /* Bottom of window, lower part */ |
| 1388 | |
| 1389 | /* |
| 1390 | * We keep the high part intact when: |
| 1391 | * 1) the seq is within [bl, 0xffffffff] and the whole window is |
| 1392 | * within one subspace; |
| 1393 | * 2) the seq is within [0, bl) and window spans two subspaces. |
| 1394 | */ |
| 1395 | if ((tl >= window - 1 && seq >= bl) || |
| 1396 | (tl < window - 1 && seq < bl)) { |
| 1397 | seqh = th; |
| 1398 | if (seq <= tl) { |
| 1399 | /* Sequence number inside window - check against replay */ |
| 1400 | if (check_window(replay, seq)) |
| 1401 | return (1); |
| 1402 | set_window(replay, seq); |
| 1403 | } else { |
| 1404 | advance_window(replay, ((uint64_t)seqh << 32) | seq); |
| 1405 | set_window(replay, seq); |
| 1406 | replay->last = ((uint64_t)seqh << 32) | seq; |
| 1407 | } |
| 1408 | |
| 1409 | /* Sequence number above top of window or not found in bitmap */ |
| 1410 | replay->count++; |
| 1411 | return (0); |
| 1412 | } |
| 1413 | |
| 1414 | if (!(sav->flags & SADB_X_SAFLAGS_ESN)) |
| 1415 | return (1); |
| 1416 | |
| 1417 | /* |
| 1418 | * Seq is within [bl, 0xffffffff] and bl is within |
| 1419 | * [0xffffffff-window, 0xffffffff]. This means we got a seq |
| 1420 | * which is within our replay window, but in the previous |
no test coverage detected