esp_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. package ike
  2. import (
  3. "bytes"
  4. "crypto/cipher"
  5. "encoding/binary"
  6. "encoding/hex"
  7. "errors"
  8. "math"
  9. "net"
  10. "testing"
  11. )
  12. type espRepeatingReader byte
  13. func (value espRepeatingReader) Read(destination []byte) (int, error) {
  14. for index := range destination {
  15. destination[index] = byte(value)
  16. }
  17. return len(destination), nil
  18. }
  19. func TestESPTunnelRoundTripNegotiatedSuites(t *testing.T) {
  20. t.Parallel()
  21. tests := []struct {
  22. name string
  23. encryption string
  24. integrity string
  25. encKey []byte
  26. authKey []byte
  27. }{
  28. {
  29. name: "AES128-SHA1",
  30. encryption: "aes-cbc-128",
  31. integrity: "hmac-sha1-96",
  32. encKey: bytes.Repeat([]byte{0x11}, 16),
  33. authKey: bytes.Repeat([]byte{0x22}, 20),
  34. },
  35. {
  36. name: "AES256-SHA256",
  37. encryption: "aes-cbc-256",
  38. integrity: "hmac-sha2-256-128",
  39. encKey: bytes.Repeat([]byte{0x33}, 32),
  40. authKey: bytes.Repeat([]byte{0x44}, 32),
  41. },
  42. }
  43. for _, test := range tests {
  44. test := test
  45. t.Run(test.name, func(t *testing.T) {
  46. t.Parallel()
  47. tunnel := mustTestESPTunnel(t, test.encryption, test.integrity, test.encKey, test.authKey)
  48. outbound := testIPv4UDPPacket(
  49. net.IPv4(10, 0, 0, 2),
  50. net.IPv4(10, 0, 0, 9),
  51. 40123,
  52. 50600,
  53. []byte("REGISTER"),
  54. )
  55. protected, err := tunnel.seal(outbound)
  56. if err != nil {
  57. t.Fatalf("seal: %v", err)
  58. }
  59. if got := binary.BigEndian.Uint32(protected[0:4]); got != 0x11223344 {
  60. t.Fatalf("SPI = %#x, want %#x", got, uint32(0x11223344))
  61. }
  62. if got := binary.BigEndian.Uint32(protected[4:8]); got != 1 {
  63. t.Fatalf("sequence = %d, want 1", got)
  64. }
  65. // A peer opens the outbound SA with the same SPI and key material.
  66. peer := mustTestESPTunnel(t, test.encryption, test.integrity, test.encKey, test.authKey)
  67. peer.initiatorSelectors, peer.responderSelectors =
  68. peer.responderSelectors, peer.initiatorSelectors
  69. cleartext, err := peer.open(protected)
  70. if err != nil {
  71. t.Fatalf("open: %v", err)
  72. }
  73. if !bytes.Equal(cleartext, outbound) {
  74. t.Fatalf("round trip changed the inner packet")
  75. }
  76. })
  77. }
  78. }
  79. func TestESPEncryptionMatchesRFC3602TunnelModeVector(t *testing.T) {
  80. t.Parallel()
  81. // RFC 3602 section 4, case #7. Authentication is intentionally outside
  82. // that RFC vector, so this assertion covers ESP SPI/sequence/IV layout,
  83. // tunnel-mode padding/trailer, and all 96 AES-CBC ciphertext octets.
  84. key := mustDecodeHex(t, "0123456789abcdef0123456789abcdef")
  85. iv := mustDecodeHex(t, "f4e765244f6407adf13dc1380f673f37")
  86. innerPacket := mustDecodeHex(t,
  87. "45000054090400004001f988c0a87b03c0a87bc8"+
  88. "08009f76a90a0100b49c083d02a20400"+
  89. "08090a0b0c0d0e0f1011121314151617"+
  90. "18191a1b1c1d1e1f2021222324252627"+
  91. "28292a2b2c2d2e2f3031323334353637",
  92. )
  93. expectedCiphertext := mustDecodeHex(t,
  94. "773b5241a4c449225e4f3ce5ed611b0c"+
  95. "237ca96cf74a93013c1b0ea1a0cf70f8"+
  96. "e4ecaec78ac53aad7a0f022b859243c6"+
  97. "47752e94a859352b8a4d4d2decd136e5"+
  98. "c177f132ad3fbfb2201ac9904c74ee0a"+
  99. "109e0ca1e4dfe9d5a100b842f1c22f0d",
  100. )
  101. direction, err := newESPDirection(
  102. 0x8765,
  103. key,
  104. bytes.Repeat([]byte{0x5a}, 20),
  105. "aes-cbc-128",
  106. "hmac-sha1-96",
  107. bytes.NewReader(iv),
  108. )
  109. if err != nil {
  110. t.Fatal(err)
  111. }
  112. direction.sequence = 1
  113. packet, err := direction.seal(innerPacket, 4)
  114. if err != nil {
  115. t.Fatal(err)
  116. }
  117. if got := packet[:8]; !bytes.Equal(got, mustDecodeHex(t, "0000876500000002")) {
  118. t.Fatalf("ESP header = %x", got)
  119. }
  120. if got := packet[8:24]; !bytes.Equal(got, iv) {
  121. t.Fatalf("ESP IV = %x", got)
  122. }
  123. if got := packet[24 : 24+len(expectedCiphertext)]; !bytes.Equal(got, expectedCiphertext) {
  124. t.Fatalf("ESP ciphertext = %x, want %x", got, expectedCiphertext)
  125. }
  126. }
  127. func TestESPRejectsTamperWrongSPIAndReplay(t *testing.T) {
  128. t.Parallel()
  129. tunnel := mustTestESPTunnel(
  130. t,
  131. "aes-cbc-128",
  132. "hmac-sha1-96",
  133. bytes.Repeat([]byte{0x51}, 16),
  134. bytes.Repeat([]byte{0x61}, 20),
  135. )
  136. peer := mustTestESPTunnel(
  137. t,
  138. "aes-cbc-128",
  139. "hmac-sha1-96",
  140. bytes.Repeat([]byte{0x51}, 16),
  141. bytes.Repeat([]byte{0x61}, 20),
  142. )
  143. peer.initiatorSelectors, peer.responderSelectors =
  144. peer.responderSelectors, peer.initiatorSelectors
  145. inner := testIPv4UDPPacket(
  146. net.IPv4(10, 0, 0, 2),
  147. net.IPv4(10, 0, 0, 9),
  148. 42000,
  149. 50600,
  150. []byte("payload"),
  151. )
  152. protected, err := tunnel.seal(inner)
  153. if err != nil {
  154. t.Fatal(err)
  155. }
  156. tampered := append([]byte(nil), protected...)
  157. tampered[len(tampered)-1] ^= 0x80
  158. if _, err := peer.open(tampered); !errors.Is(err, errESPAuthentication) {
  159. t.Fatalf("tampered packet error = %v, want authentication failure", err)
  160. }
  161. wrongSPI := append([]byte(nil), protected...)
  162. wrongSPI[0] ^= 0x01
  163. if _, err := peer.open(wrongSPI); err == nil {
  164. t.Fatal("packet with wrong SPI was accepted")
  165. }
  166. if _, err := peer.open(protected); err != nil {
  167. t.Fatalf("first authenticated packet: %v", err)
  168. }
  169. if _, err := peer.open(protected); !errors.Is(err, errESPReplay) {
  170. t.Fatalf("replayed packet error = %v, want replay rejection", err)
  171. }
  172. }
  173. func TestESPReplayWindowAcceptsAuthenticatedReordering(t *testing.T) {
  174. t.Parallel()
  175. sender := mustDefaultESPTunnel(t)
  176. receiver := mustDefaultESPTunnel(t)
  177. receiver.initiatorSelectors, receiver.responderSelectors =
  178. receiver.responderSelectors, receiver.initiatorSelectors
  179. var protected [][]byte
  180. for index := 0; index < 3; index++ {
  181. packet := testIPv4UDPPacket(
  182. net.IPv4(10, 0, 0, 2),
  183. net.IPv4(10, 0, 0, 9),
  184. uint16(40000+index),
  185. 50600,
  186. []byte{byte(index)},
  187. )
  188. value, err := sender.seal(packet)
  189. if err != nil {
  190. t.Fatal(err)
  191. }
  192. protected = append(protected, value)
  193. }
  194. for _, index := range []int{2, 0, 1} {
  195. if _, err := receiver.open(protected[index]); err != nil {
  196. t.Fatalf("open sequence %d: %v", index+1, err)
  197. }
  198. }
  199. if _, err := receiver.open(protected[0]); !errors.Is(err, errESPReplay) {
  200. t.Fatalf("duplicate reordered packet error = %v", err)
  201. }
  202. }
  203. func TestESPRejectsAuthenticatedInvalidPaddingWithoutConsumingSequence(t *testing.T) {
  204. t.Parallel()
  205. sender := mustDefaultESPTunnel(t)
  206. receiver := mustDefaultESPTunnel(t)
  207. receiver.initiatorSelectors, receiver.responderSelectors =
  208. receiver.responderSelectors, receiver.initiatorSelectors
  209. inner := testIPv4UDPPacket(
  210. net.IPv4(10, 0, 0, 2),
  211. net.IPv4(10, 0, 0, 9),
  212. 40000,
  213. 50600,
  214. []byte("one"),
  215. )
  216. protected, err := sender.seal(inner)
  217. if err != nil {
  218. t.Fatal(err)
  219. }
  220. malformed := append([]byte(nil), protected...)
  221. rewriteESPPlaintext(t, receiver.inbound, malformed, func(plaintext []byte) {
  222. paddingLength := int(plaintext[len(plaintext)-2])
  223. if paddingLength == 0 {
  224. plaintext[len(plaintext)-2] = 1
  225. plaintext[len(plaintext)-3] = 0xff
  226. return
  227. }
  228. plaintext[len(plaintext)-2-paddingLength] ^= 0xff
  229. })
  230. if _, err := receiver.open(malformed); err == nil {
  231. t.Fatal("authenticated packet with invalid padding was accepted")
  232. }
  233. if _, err := receiver.open(protected); err != nil {
  234. t.Fatalf("invalid packet consumed the sequence number: %v", err)
  235. }
  236. }
  237. func TestESPTrafficSelectorsAreEnforcedInBothDirections(t *testing.T) {
  238. t.Parallel()
  239. tunnel := mustDefaultESPTunnel(t)
  240. disallowed := testIPv4UDPPacket(
  241. net.IPv4(10, 0, 0, 2),
  242. net.IPv4(203, 0, 113, 10),
  243. 40000,
  244. 50600,
  245. nil,
  246. )
  247. if _, err := tunnel.seal(disallowed); err == nil {
  248. t.Fatal("outbound packet outside responder selector was accepted")
  249. }
  250. sender := mustDefaultESPTunnel(t)
  251. receiver := mustDefaultESPTunnel(t)
  252. receiver.initiatorSelectors, receiver.responderSelectors =
  253. receiver.responderSelectors, receiver.initiatorSelectors
  254. allowed := testIPv4UDPPacket(
  255. net.IPv4(10, 0, 0, 2),
  256. net.IPv4(10, 0, 0, 9),
  257. 40000,
  258. 50600,
  259. nil,
  260. )
  261. protected, err := sender.seal(allowed)
  262. if err != nil {
  263. t.Fatal(err)
  264. }
  265. rewriteESPPlaintext(t, receiver.inbound, protected, func(plaintext []byte) {
  266. copy(plaintext[16:20], net.IPv4(203, 0, 113, 10).To4())
  267. })
  268. if _, err := receiver.open(protected); err == nil {
  269. t.Fatal("authenticated inbound packet outside selectors was accepted")
  270. }
  271. }
  272. func TestESPSequenceExhaustionRequiresRekey(t *testing.T) {
  273. t.Parallel()
  274. tunnel := mustDefaultESPTunnel(t)
  275. tunnel.outbound.sequence = math.MaxUint32
  276. packet := testIPv4UDPPacket(
  277. net.IPv4(10, 0, 0, 2),
  278. net.IPv4(10, 0, 0, 9),
  279. 40000,
  280. 50600,
  281. nil,
  282. )
  283. if _, err := tunnel.seal(packet); err == nil {
  284. t.Fatal("ESP sequence wrapped instead of requiring rekey")
  285. }
  286. }
  287. func TestParseInnerIPv6ESP(t *testing.T) {
  288. t.Parallel()
  289. packet := make([]byte, 40+8)
  290. packet[0] = 0x60
  291. binary.BigEndian.PutUint16(packet[4:6], 8)
  292. packet[6] = 50
  293. packet[7] = 64
  294. copy(packet[8:24], net.ParseIP("2001:db8::1").To16())
  295. copy(packet[24:40], net.ParseIP("2001:db8::2").To16())
  296. metadata, err := parseInnerPacket(packet)
  297. if err != nil {
  298. t.Fatal(err)
  299. }
  300. if metadata.protocol != 50 || metadata.nextHeader != 41 {
  301. t.Fatalf("metadata = %+v", metadata)
  302. }
  303. }
  304. func mustDefaultESPTunnel(t *testing.T) *espTunnel {
  305. t.Helper()
  306. return mustTestESPTunnel(
  307. t,
  308. "aes-cbc-128",
  309. "hmac-sha1-96",
  310. bytes.Repeat([]byte{0x31}, 16),
  311. bytes.Repeat([]byte{0x41}, 20),
  312. )
  313. }
  314. func mustTestESPTunnel(
  315. t *testing.T,
  316. encryption string,
  317. integrity string,
  318. encryptionKey []byte,
  319. authenticationKey []byte,
  320. ) *espTunnel {
  321. t.Helper()
  322. selector := func(ip net.IP) trafficSelector {
  323. return trafficSelector{
  324. StartPort: 0,
  325. EndPort: 65535,
  326. StartIP: append(net.IP(nil), ip.To4()...),
  327. EndIP: append(net.IP(nil), ip.To4()...),
  328. }
  329. }
  330. tunnel, err := newESPTunnel(ChildSAConfig{
  331. InboundSPI: 0x11223344,
  332. OutboundSPI: 0x11223344,
  333. Encryption: encryption,
  334. Integrity: integrity,
  335. InboundEncKey: encryptionKey,
  336. InboundAuthKey: authenticationKey,
  337. OutboundEncKey: encryptionKey,
  338. OutboundAuthKey: authenticationKey,
  339. InitiatorSelectors: []trafficSelector{selector(net.IPv4(10, 0, 0, 2))},
  340. ResponderSelectors: []trafficSelector{selector(net.IPv4(10, 0, 0, 9))},
  341. }, espRepeatingReader(0xa5))
  342. if err != nil {
  343. t.Fatal(err)
  344. }
  345. return tunnel
  346. }
  347. func testIPv4UDPPacket(
  348. source net.IP,
  349. destination net.IP,
  350. sourcePort uint16,
  351. destinationPort uint16,
  352. payload []byte,
  353. ) []byte {
  354. packet := make([]byte, 20+8+len(payload))
  355. packet[0] = 0x45
  356. binary.BigEndian.PutUint16(packet[2:4], uint16(len(packet)))
  357. packet[8] = 64
  358. packet[9] = 17
  359. copy(packet[12:16], source.To4())
  360. copy(packet[16:20], destination.To4())
  361. binary.BigEndian.PutUint16(packet[20:22], sourcePort)
  362. binary.BigEndian.PutUint16(packet[22:24], destinationPort)
  363. binary.BigEndian.PutUint16(packet[24:26], uint16(8+len(payload)))
  364. copy(packet[28:], payload)
  365. return packet
  366. }
  367. func rewriteESPPlaintext(
  368. t *testing.T,
  369. direction *espDirection,
  370. packet []byte,
  371. rewrite func([]byte),
  372. ) {
  373. t.Helper()
  374. blockSize := direction.block.BlockSize()
  375. authenticatedLength := len(packet) - direction.icvLength
  376. iv := packet[espHeaderLength : espHeaderLength+blockSize]
  377. ciphertext := packet[espHeaderLength+blockSize : authenticatedLength]
  378. plaintext := make([]byte, len(ciphertext))
  379. cipher.NewCBCDecrypter(direction.block, iv).CryptBlocks(plaintext, ciphertext)
  380. rewrite(plaintext)
  381. cipher.NewCBCEncrypter(direction.block, iv).CryptBlocks(ciphertext, plaintext)
  382. copy(packet[authenticatedLength:], direction.authenticationCode(packet[:authenticatedLength]))
  383. }
  384. func mustDecodeHex(t *testing.T, value string) []byte {
  385. t.Helper()
  386. decoded, err := hex.DecodeString(value)
  387. if err != nil {
  388. t.Fatal(err)
  389. }
  390. return decoded
  391. }