skip to content

A 1,400-byte IPv4 packet is protected by IPsec ESP with AES-GCM and a 16-byte ICV; how large is it in transport and tunnel mode?

level: middleimportance: should knowfreq 28%

answer

  1. count every field, not just ESP
  2. IV, trailer, ICV
  3. what gets padded, and to what
  4. transport keeps the 20-byte header

basics

~20 s

With IPsec ESP and AES-GCM (8-byte IV, 16-byte ICV), the 1,400-byte IPv4 packet becomes 1,436 bytes in transport mode (36 bytes added) and 1,456 bytes in tunnel mode (56 added), the difference being the outer IPv4 header.

solid answer

~50 s

Add the fields. ESP brings an 8-byte header (`SPI` 4 + sequence number 4), the transform's IV (8 bytes for AES-GCM, RFC 4106), a trailer of padding plus `Pad Length` and `Next Header` (2 bytes), and the ICV (16 bytes for the 16-octet GCM tag). AES-GCM needs no block padding, only 4-byte alignment. In **transport mode** the 20-byte header stays in clear and the 1,380 bytes behind it are encrypted: 1,380 + 2 = 1,382, padded by 2 to 1,384, so 20 + 8 + 8 + 1,384 + 16 = **1,436**. In **tunnel mode** all 1,400 bytes are encrypted: 1,402, padded to 1,404, plus a new 20-byte header: 20 + 8 + 8 + 1,404 + 16 = **1,456**. With AES-CBC and `AUTH_HMAC_SHA2_256_128` the figures become 1,452 and 1,468, because CBC pads to 16-byte blocks.

code

pseudocode · 15 lines
pseudocode
function esp_wire_size(mode, packet_len, ip_header_len, outer_header_len, iv_len, icv_len, block):
    if mode == TRANSPORT:
        protected = packet_len - ip_header_len   // data after the kept header
        front = ip_header_len                   // original header, in clear
    else:                                       // TUNNEL
        protected = packet_len                  // whole inner packet
        front = outer_header_len                // new outer header
    align = max(block, 4)                       // GCM: 4, CBC: 16
    plain = protected + 2                       // + Pad Length + Next Header
    pad = (align - plain mod align) mod align
    return front + 8 + iv_len + plain + pad + icv_len   // 8 = SPI + Sequence Number

// esp_wire_size(TRANSPORT, 1400, 20, 20, 8, 16, 1)  = 1436
// esp_wire_size(TUNNEL,    1400, 20, 20, 8, 16, 1)  = 1456
// esp_wire_size(TUNNEL,    1400, 20, 20, 16, 16, 16) = 1468

go deeper

for a junior

Recall the pieces ESP adds — header, IV, trailer, ICV — and that tunnel mode also adds a whole IP header.

for a middle

Compute both modes for a given packet and cipher, showing the padding step, and explain why transport mode encrypts 20 bytes less.

for a senior

Recompute overhead per cipher instead of quoting one number, and show why a block cipher's padding makes the mode difference vary with packet size.

for a principal

Use the arithmetic to argue cipher and mode choices across an estate: AES-GCM's smaller IV and single tag versus CBC with HMAC, and IPv6 outers.

## The fields ESP adds An ESP packet (RFC 4303) wraps its protected data in fixed fields and a variable trailer: - **ESP header** — Security Parameters Index (4 bytes) and Sequence Number (4 bytes): **8 bytes**. - **IV** — set by the transform. AES-GCM in ESP (RFC 4106) uses an **8-byte** explicit IV; AES-CBC (RFC 3602) uses a **16-byte** IV, one cipher block. - **Padding** — 0 to 255 bytes, for two reasons: a block cipher needs the plaintext (data + padding + `Pad Length` + `Next Header`) to be a multiple of its block size, and in every case the trailer must end on a 4-byte boundary so the ICV is aligned. - **Pad Length** and **Next Header** — 1 byte each: **2 bytes**. - **ICV** — the integrity check value, sized by the algorithm: **16 bytes** for the full AES-GCM tag (`ENCR_AES_GCM_16`), 16 for `AUTH_HMAC_SHA2_256_128`, 12 for the older `AUTH_HMAC_SHA1_96`. RFC 4106 §7 summarises AES-GCM's expansion: the IV adds 8 bytes, the ICV 8, 12 or 16, and the SPI, sequence number, padding, pad length and next header take 10 to 13 bytes with minimal padding. ## Transport mode: encrypt what follows the header In transport mode the original 20-byte IPv4 header is reused, so only the 1,380 bytes behind it are encrypted. 1. Plaintext before padding: 1,380 + 2 (trailer bytes) = 1,382. 2. AES-GCM needs only 4-byte alignment: 1,382 is 2 short of a multiple of 4, so **2 bytes of padding**, giving 1,384. 3. On the wire: 20 (original header) + 8 (ESP header) + 8 (IV) + 1,384 + 16 (ICV) = **1,436 bytes**, i.e. **36 bytes** of overhead. ## Tunnel mode: encrypt the whole packet, add a header 1. Plaintext before padding: 1,400 + 2 = 1,402. 2. 1,402 is also 2 short of a multiple of 4: **2 bytes of padding**, giving 1,404. 3. On the wire: 20 (new outer header) + 8 + 8 + 1,404 + 16 = **1,456 bytes**, i.e. **56 bytes** of overhead. | Field | Transport | Tunnel | |---|---|---| | IPv4 header in front of ESP | 20 (original) | 20 (new outer) | | ESP header | 8 | 8 | | AES-GCM IV | 8 | 8 | | Encrypted data | 1,380 | 1,400 | | Padding | 2 | 2 | | Pad Length + Next Header | 2 | 2 | | ICV | 16 | 16 | | **Total** | **1,436** | **1,456** | ## Why the gap is not always 20 bytes With AES-GCM the padding was 2 bytes in both modes, so the difference is exactly the outer header. With a block cipher it need not be. Take AES-CBC (16-byte IV, 16-byte blocks) with `AUTH_HMAC_SHA2_256_128` (16-byte ICV): - Transport: 1,382 rounds up to 1,392 (10 bytes of padding) → 20 + 8 + 16 + 1,392 + 16 = **1,452**. - Tunnel: 1,402 rounds up to 1,408 (6 bytes of padding) → 20 + 8 + 16 + 1,408 + 16 = **1,468**. The tunnel adds 20 header bytes, but needs 4 fewer padding bytes, so the gap is **16**. Padding depends on the exact length, so recompute it for each packet size rather than carrying a fixed overhead around. Two facts help: RFC 4303 leaves the IV out when padding to the block size, and minimal padding is always shorter than one block (under four bytes for AES-GCM, per RFC 4106). ## Variations worth knowing - **IPv6 outer header**: 40 bytes instead of 20, so the AES-GCM tunnel packet becomes 1,476 bytes. - **A shorter AES-GCM ICV**: RFC 4106 lets an implementation also offer 8- or 12-octet ICVs, which cut 8 or 4 bytes from every figure; it MUST support the full 16-octet tag, and it warns that shorter tags are easier to forge. - **IPv6 transport mode**: the original 40-byte header and any extension headers placed before ESP stay in clear, so the encrypted portion is whatever follows them, and the same padding rule applies. - **Other IPsec layers**: UDP encapsulation for NAT traversal adds its own header on top of these figures; it is a separate mechanism, not part of either mode. - **AES-CBC** is still a MUST in RFC 8221, but `ENCR_AES_GCM_16` is the MUST that also saves the separate HMAC and 8 bytes of IV.

  • With AES-CBC and a 16-byte ICV, why does tunnel mode add only 16 bytes over transport mode for this packet?
    Because the padding changes with length. Transport mode encrypts 1,382 bytes, which pad up to 1,392 (10 bytes); tunnel mode encrypts 1,402, which pad up to 1,408 (6 bytes). The new 20-byte outer header is offset by 4 fewer padding bytes, so 1,468 - 1,452 = 16.
  • How does the AES-GCM tunnel-mode figure change if the outer header is IPv6?
    The outer header grows from 20 to 40 bytes and nothing else changes, since the padding depends only on the inner packet: 40 + 8 + 8 + 1,404 + 16 = 1,476 bytes, or 76 bytes of overhead. IPsec allows the outer version to differ from the inner one.

saying these in an interview costs you the question

  • Tunnel mode always costs exactly 20 bytes more than transport mode
  • ESP overhead is a fixed number of bytes whatever the cipher
  • AES-GCM in ESP pads to 16-byte blocks like AES-CBC
  • The 8-byte ESP header is the whole overhead ESP adds
  • The IV is counted when padding the plaintext to the block size