1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* OpenVPN data channel offload 3 * 4 * Copyright (C) 2020-2025 OpenVPN, Inc. 5 * 6 * Author: Antonio Quartulli <antonio@openvpn.net> 7 * James Yonan <james@openvpn.net> 8 */ 9 10 #ifndef _NET_OVPN_OVPNPKTID_H_ 11 #define _NET_OVPN_OVPNPKTID_H_ 12 13 #include "proto.h" 14 15 /* If no packets received for this length of time, set a backtrack floor 16 * at highest received packet ID thus far. 17 */ 18 #define PKTID_RECV_EXPIRE (30 * HZ) 19 20 /* Packet-ID state for transmitter */ 21 struct ovpn_pktid_xmit { 22 atomic_t seq_num; 23 }; 24 25 /* replay window sizing in bytes = 2^REPLAY_WINDOW_ORDER */ 26 #define REPLAY_WINDOW_ORDER 8 27 28 #define REPLAY_WINDOW_BYTES BIT(REPLAY_WINDOW_ORDER) 29 #define REPLAY_WINDOW_SIZE (REPLAY_WINDOW_BYTES * 8) 30 #define REPLAY_INDEX(base, i) (((base) + (i)) & (REPLAY_WINDOW_SIZE - 1)) 31 32 /* Packet-ID state for receiver. 33 * Other than lock member, can be zeroed to initialize. 34 */ 35 struct ovpn_pktid_recv { 36 /* "sliding window" bitmask of recent packet IDs received */ 37 u8 history[REPLAY_WINDOW_BYTES]; 38 /* bit position of deque base in history */ 39 unsigned int base; 40 /* extent (in bits) of deque in history */ 41 unsigned int extent; 42 /* expiration of history in jiffies */ 43 unsigned long expire; 44 /* highest sequence number received */ 45 u32 id; 46 /* highest time stamp received */ 47 u32 time; 48 /* we will only accept backtrack IDs > id_floor */ 49 u32 id_floor; 50 unsigned int max_backtrack; 51 /* protects entire pktd ID state */ 52 spinlock_t lock; 53 }; 54 55 /* Get the next packet ID for xmit */ 56 static inline int ovpn_pktid_xmit_next(struct ovpn_pktid_xmit *pid, u32 *pktid) 57 { 58 const u32 seq_num = atomic_fetch_add_unless(&pid->seq_num, 1, 0); 59 /* when the 32bit space is over, we return an error because the packet 60 * ID is used to create the cipher IV and we do not want to reuse the 61 * same value more than once 62 */ 63 if (unlikely(!seq_num)) 64 return -ERANGE; 65 66 *pktid = seq_num; 67 68 return 0; 69 } 70 71 /* Write 12-byte AEAD IV to dest */ 72 static inline void ovpn_pktid_aead_write(const u32 pktid, 73 const u8 nt[], 74 unsigned char *dest) 75 { 76 *(__force __be32 *)(dest) = htonl(pktid); 77 BUILD_BUG_ON(4 + OVPN_NONCE_TAIL_SIZE != OVPN_NONCE_SIZE); 78 memcpy(dest + 4, nt, OVPN_NONCE_TAIL_SIZE); 79 } 80 81 void ovpn_pktid_xmit_init(struct ovpn_pktid_xmit *pid); 82 void ovpn_pktid_recv_init(struct ovpn_pktid_recv *pr); 83 84 int ovpn_pktid_recv(struct ovpn_pktid_recv *pr, u32 pkt_id, u32 pkt_time); 85 86 #endif /* _NET_OVPN_OVPNPKTID_H_ */ 87