1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.cts; 18 19 import static android.system.OsConstants.IPPROTO_TCP; 20 import static android.system.OsConstants.IPPROTO_UDP; 21 import static org.junit.Assert.assertArrayEquals; 22 import static org.junit.Assert.assertTrue; 23 24 import android.content.Context; 25 import android.net.ConnectivityManager; 26 import android.net.IpSecAlgorithm; 27 import android.net.IpSecManager; 28 import android.net.IpSecTransform; 29 import android.net.TrafficStats; 30 import android.system.ErrnoException; 31 import android.system.Os; 32 import android.system.OsConstants; 33 34 import java.io.FileDescriptor; 35 import java.io.IOException; 36 import java.net.DatagramPacket; 37 import java.net.DatagramSocket; 38 import java.net.Inet6Address; 39 import java.net.InetAddress; 40 import java.net.UnknownHostException; 41 import java.util.Arrays; 42 43 public class IpSecManagerTest extends IpSecBaseTest { 44 45 private static final String TAG = IpSecManagerTest.class.getSimpleName(); 46 47 private ConnectivityManager mCM; 48 49 private static InetAddress IpAddress(String addrString) { 50 try { 51 return InetAddress.getByName(addrString); 52 } catch (UnknownHostException e) { 53 throw new IllegalArgumentException("Invalid IP address: " + e); 54 } 55 } 56 57 private static final InetAddress GOOGLE_DNS_4 = IpAddress("8.8.8.8"); 58 private static final InetAddress GOOGLE_DNS_6 = IpAddress("2001:4860:4860::8888"); 59 60 private static final InetAddress[] GOOGLE_DNS_LIST = 61 new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6}; 62 63 private static final int DROID_SPI = 0xD1201D; 64 private static final int MAX_PORT_BIND_ATTEMPTS = 10; 65 66 private static final byte[] AEAD_KEY = getKey(288); 67 68 private static final int TCP_HDRLEN_WITH_OPTIONS = 32; 69 private static final int UDP_HDRLEN = 8; 70 private static final int IP4_HDRLEN = 20; 71 private static final int IP6_HDRLEN = 40; 72 73 // Encryption parameters 74 private static final int AES_GCM_IV_LEN = 8; 75 private static final int AES_CBC_IV_LEN = 16; 76 private static final int AES_GCM_BLK_SIZE = 4; 77 private static final int AES_CBC_BLK_SIZE = 16; 78 79 protected void setUp() throws Exception { 80 super.setUp(); 81 mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); 82 } 83 84 /* 85 * Allocate a random SPI 86 * Allocate a specific SPI using previous randomly created SPI value 87 * Realloc the same SPI that was specifically created (expect SpiUnavailable) 88 * Close SPIs 89 */ 90 public void testAllocSpi() throws Exception { 91 for (InetAddress addr : GOOGLE_DNS_LIST) { 92 IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null; 93 randomSpi = mISM.allocateSecurityParameterIndex(addr); 94 assertTrue( 95 "Failed to receive a valid SPI", 96 randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); 97 98 droidSpi = mISM.allocateSecurityParameterIndex(addr, DROID_SPI); 99 assertTrue("Failed to allocate specified SPI, " + DROID_SPI, 100 droidSpi.getSpi() == DROID_SPI); 101 102 try { 103 mISM.allocateSecurityParameterIndex(addr, DROID_SPI); 104 fail("Duplicate SPI was allowed to be created"); 105 } catch (IpSecManager.SpiUnavailableException expected) { 106 // This is a success case because we expect a dupe SPI to throw 107 } 108 109 randomSpi.close(); 110 droidSpi.close(); 111 } 112 } 113 114 /** This function finds an available port */ 115 private static int findUnusedPort() throws Exception { 116 // Get an available port. 117 DatagramSocket s = new DatagramSocket(); 118 int port = s.getLocalPort(); 119 s.close(); 120 return port; 121 } 122 123 private static FileDescriptor getBoundUdpSocket(InetAddress address) throws Exception { 124 FileDescriptor sock = 125 Os.socket(getDomain(address), OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP); 126 127 for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) { 128 try { 129 int port = findUnusedPort(); 130 Os.bind(sock, address, port); 131 break; 132 } catch (ErrnoException e) { 133 // Someone claimed the port since we called findUnusedPort. 134 if (e.errno == OsConstants.EADDRINUSE) { 135 if (i == MAX_PORT_BIND_ATTEMPTS - 1) { 136 137 fail("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port"); 138 } 139 continue; 140 } 141 throw e.rethrowAsIOException(); 142 } 143 } 144 return sock; 145 } 146 147 private void checkUnconnectedUdp(IpSecTransform transform, InetAddress local, int sendCount, 148 boolean useJavaSockets) throws Exception { 149 GenericUdpSocket sockLeft = null, sockRight = null; 150 if (useJavaSockets) { 151 SocketPair<JavaUdpSocket> sockets = getJavaUdpSocketPair(local, mISM, transform, false); 152 sockLeft = sockets.mLeftSock; 153 sockRight = sockets.mRightSock; 154 } else { 155 SocketPair<NativeUdpSocket> sockets = 156 getNativeUdpSocketPair(local, mISM, transform, false); 157 sockLeft = sockets.mLeftSock; 158 sockRight = sockets.mRightSock; 159 } 160 161 for (int i = 0; i < sendCount; i++) { 162 byte[] in; 163 164 sockLeft.sendTo(TEST_DATA, local, sockRight.getPort()); 165 in = sockRight.receive(); 166 assertArrayEquals("Left-to-right encrypted data did not match.", TEST_DATA, in); 167 168 sockRight.sendTo(TEST_DATA, local, sockLeft.getPort()); 169 in = sockLeft.receive(); 170 assertArrayEquals("Right-to-left encrypted data did not match.", TEST_DATA, in); 171 } 172 173 sockLeft.close(); 174 sockRight.close(); 175 } 176 177 private void checkTcp(IpSecTransform transform, InetAddress local, int sendCount, 178 boolean useJavaSockets) throws Exception { 179 GenericTcpSocket client = null, accepted = null; 180 if (useJavaSockets) { 181 SocketPair<JavaTcpSocket> sockets = getJavaTcpSocketPair(local, mISM, transform); 182 client = sockets.mLeftSock; 183 accepted = sockets.mRightSock; 184 } else { 185 SocketPair<NativeTcpSocket> sockets = getNativeTcpSocketPair(local, mISM, transform); 186 client = sockets.mLeftSock; 187 accepted = sockets.mRightSock; 188 } 189 190 // Wait for TCP handshake packets to be counted 191 StatsChecker.waitForNumPackets(3); // (SYN, SYN+ACK, ACK) 192 193 // Reset StatsChecker, to ignore negotiation overhead. 194 StatsChecker.initStatsChecker(); 195 for (int i = 0; i < sendCount; i++) { 196 byte[] in; 197 198 client.send(TEST_DATA); 199 in = accepted.receive(); 200 assertArrayEquals("Client-to-server encrypted data did not match.", TEST_DATA, in); 201 202 // Allow for newest data + ack packets to be returned before sending next packet 203 // Also add the number of expected packets in each of the previous runs (4 per run) 204 StatsChecker.waitForNumPackets(2 + (4 * i)); 205 206 accepted.send(TEST_DATA); 207 in = client.receive(); 208 assertArrayEquals("Server-to-client encrypted data did not match.", TEST_DATA, in); 209 210 // Allow for all data + ack packets to be returned before sending next packet 211 // Also add the number of expected packets in each of the previous runs (4 per run) 212 StatsChecker.waitForNumPackets(4 * (i + 1)); 213 } 214 215 // Transforms should not be removed from the sockets, otherwise FIN packets will be sent 216 // unencrypted. 217 // This test also unfortunately happens to rely on a nuance of the cleanup order. By 218 // keeping the policy on the socket, but removing the SA before lingering FIN packets 219 // are sent (at an undetermined later time), the FIN packets are dropped. Without this, 220 // we run into all kinds of headaches trying to test data accounting (unsolicited 221 // packets mysteriously appearing and messing up our counters) 222 // The right way to close sockets is to set SO_LINGER to ensure synchronous closure, 223 // closing the sockets, and then closing the transforms. See documentation for the 224 // Socket or FileDescriptor flavors of applyTransportModeTransform() in IpSecManager 225 // for more details. 226 227 client.close(); 228 accepted.close(); 229 } 230 231 /* 232 * Alloc outbound SPI 233 * Alloc inbound SPI 234 * Create transport mode transform 235 * open socket 236 * apply transform to socket 237 * send data on socket 238 * release transform 239 * send data (expect exception) 240 */ 241 public void testCreateTransform() throws Exception { 242 InetAddress localAddr = InetAddress.getByName(IPV4_LOOPBACK); 243 IpSecManager.SecurityParameterIndex spi = 244 mISM.allocateSecurityParameterIndex(localAddr); 245 246 IpSecTransform transform = 247 new IpSecTransform.Builder(mContext) 248 .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) 249 .setAuthentication( 250 new IpSecAlgorithm( 251 IpSecAlgorithm.AUTH_HMAC_SHA256, 252 AUTH_KEY, 253 AUTH_KEY.length * 8)) 254 .buildTransportModeTransform(localAddr, spi); 255 256 final boolean [][] applyInApplyOut = { 257 {false, false}, {false, true}, {true, false}, {true,true}}; 258 final byte[] data = new String("Best test data ever!").getBytes("UTF-8"); 259 final DatagramPacket outPacket = new DatagramPacket(data, 0, data.length, localAddr, 0); 260 261 byte[] in = new byte[data.length]; 262 DatagramPacket inPacket = new DatagramPacket(in, in.length); 263 DatagramSocket localSocket; 264 int localPort; 265 266 for(boolean[] io : applyInApplyOut) { 267 boolean applyIn = io[0]; 268 boolean applyOut = io[1]; 269 // Bind localSocket to a random available port. 270 localSocket = new DatagramSocket(0); 271 localPort = localSocket.getLocalPort(); 272 localSocket.setSoTimeout(200); 273 outPacket.setPort(localPort); 274 if (applyIn) { 275 mISM.applyTransportModeTransform( 276 localSocket, IpSecManager.DIRECTION_IN, transform); 277 } 278 if (applyOut) { 279 mISM.applyTransportModeTransform( 280 localSocket, IpSecManager.DIRECTION_OUT, transform); 281 } 282 if (applyIn == applyOut) { 283 localSocket.send(outPacket); 284 localSocket.receive(inPacket); 285 assertTrue("Encapsulated data did not match.", 286 Arrays.equals(outPacket.getData(), inPacket.getData())); 287 mISM.removeTransportModeTransforms(localSocket); 288 localSocket.close(); 289 } else { 290 try { 291 localSocket.send(outPacket); 292 localSocket.receive(inPacket); 293 } catch (IOException e) { 294 continue; 295 } finally { 296 mISM.removeTransportModeTransforms(localSocket); 297 localSocket.close(); 298 } 299 // FIXME: This check is disabled because sockets currently receive data 300 // if there is a valid SA for decryption, even when the input policy is 301 // not applied to a socket. 302 // fail("Data IO should fail on asymmetrical transforms! + Input=" 303 // + applyIn + " Output=" + applyOut); 304 } 305 } 306 transform.close(); 307 } 308 309 /** Snapshot of TrafficStats as of initStatsChecker call for later comparisons */ 310 private static class StatsChecker { 311 private static final double ERROR_MARGIN_BYTES = 1.05; 312 private static final double ERROR_MARGIN_PKTS = 1.05; 313 private static final int MAX_WAIT_TIME_MILLIS = 1000; 314 315 private static long uidTxBytes; 316 private static long uidRxBytes; 317 private static long uidTxPackets; 318 private static long uidRxPackets; 319 320 private static long ifaceTxBytes; 321 private static long ifaceRxBytes; 322 private static long ifaceTxPackets; 323 private static long ifaceRxPackets; 324 325 /** 326 * This method counts the number of incoming packets, polling intermittently up to 327 * MAX_WAIT_TIME_MILLIS. 328 */ 329 private static void waitForNumPackets(int numPackets) throws Exception { 330 long uidTxDelta = 0; 331 long uidRxDelta = 0; 332 for (int i = 0; i < 100; i++) { 333 uidTxDelta = TrafficStats.getUidTxPackets(Os.getuid()) - uidTxPackets; 334 uidRxDelta = TrafficStats.getUidRxPackets(Os.getuid()) - uidRxPackets; 335 336 // TODO: Check Rx packets as well once kernel security policy bug is fixed. 337 // (b/70635417) 338 if (uidTxDelta >= numPackets) { 339 return; 340 } 341 Thread.sleep(MAX_WAIT_TIME_MILLIS / 100); 342 } 343 fail( 344 "Not enough traffic was recorded to satisfy the provided conditions: wanted " 345 + numPackets 346 + ", got " 347 + uidTxDelta 348 + " tx and " 349 + uidRxDelta 350 + " rx packets"); 351 } 352 353 private static void assertUidStatsDelta( 354 int expectedTxByteDelta, 355 int expectedTxPacketDelta, 356 int minRxByteDelta, 357 int maxRxByteDelta, 358 int expectedRxPacketDelta) { 359 long newUidTxBytes = TrafficStats.getUidTxBytes(Os.getuid()); 360 long newUidRxBytes = TrafficStats.getUidRxBytes(Os.getuid()); 361 long newUidTxPackets = TrafficStats.getUidTxPackets(Os.getuid()); 362 long newUidRxPackets = TrafficStats.getUidRxPackets(Os.getuid()); 363 364 assertEquals(expectedTxByteDelta, newUidTxBytes - uidTxBytes); 365 assertTrue( 366 newUidRxBytes - uidRxBytes >= minRxByteDelta 367 && newUidRxBytes - uidRxBytes <= maxRxByteDelta); 368 assertEquals(expectedTxPacketDelta, newUidTxPackets - uidTxPackets); 369 assertEquals(expectedRxPacketDelta, newUidRxPackets - uidRxPackets); 370 } 371 372 private static void assertIfaceStatsDelta( 373 int expectedTxByteDelta, 374 int expectedTxPacketDelta, 375 int expectedRxByteDelta, 376 int expectedRxPacketDelta) 377 throws IOException { 378 long newIfaceTxBytes = TrafficStats.getLoopbackTxBytes(); 379 long newIfaceRxBytes = TrafficStats.getLoopbackRxBytes(); 380 long newIfaceTxPackets = TrafficStats.getLoopbackTxPackets(); 381 long newIfaceRxPackets = TrafficStats.getLoopbackRxPackets(); 382 383 // Check that iface stats are within an acceptable range; data might be sent 384 // on the local interface by other apps. 385 assertApproxEquals( 386 ifaceTxBytes, newIfaceTxBytes, expectedTxByteDelta, ERROR_MARGIN_BYTES); 387 assertApproxEquals( 388 ifaceRxBytes, newIfaceRxBytes, expectedRxByteDelta, ERROR_MARGIN_BYTES); 389 assertApproxEquals( 390 ifaceTxPackets, newIfaceTxPackets, expectedTxPacketDelta, ERROR_MARGIN_PKTS); 391 assertApproxEquals( 392 ifaceRxPackets, newIfaceRxPackets, expectedRxPacketDelta, ERROR_MARGIN_PKTS); 393 } 394 395 private static void assertApproxEquals( 396 long oldStats, long newStats, int expectedDelta, double errorMargin) { 397 assertTrue(expectedDelta <= newStats - oldStats); 398 assertTrue((expectedDelta * errorMargin) > newStats - oldStats); 399 } 400 401 private static void initStatsChecker() throws Exception { 402 uidTxBytes = TrafficStats.getUidTxBytes(Os.getuid()); 403 uidRxBytes = TrafficStats.getUidRxBytes(Os.getuid()); 404 uidTxPackets = TrafficStats.getUidTxPackets(Os.getuid()); 405 uidRxPackets = TrafficStats.getUidRxPackets(Os.getuid()); 406 407 ifaceTxBytes = TrafficStats.getLoopbackTxBytes(); 408 ifaceRxBytes = TrafficStats.getLoopbackRxBytes(); 409 ifaceTxPackets = TrafficStats.getLoopbackTxPackets(); 410 ifaceRxPackets = TrafficStats.getLoopbackRxPackets(); 411 } 412 } 413 414 private int getTruncLenBits(IpSecAlgorithm authOrAead) { 415 return authOrAead == null ? 0 : authOrAead.getTruncationLengthBits(); 416 } 417 418 private int getIvLen(IpSecAlgorithm cryptOrAead) { 419 if (cryptOrAead == null) { return 0; } 420 421 switch (cryptOrAead.getName()) { 422 case IpSecAlgorithm.CRYPT_AES_CBC: 423 return AES_CBC_IV_LEN; 424 case IpSecAlgorithm.AUTH_CRYPT_AES_GCM: 425 return AES_GCM_IV_LEN; 426 default: 427 throw new IllegalArgumentException( 428 "IV length unknown for algorithm" + cryptOrAead.getName()); 429 } 430 } 431 432 private int getBlkSize(IpSecAlgorithm cryptOrAead) { 433 // RFC 4303, section 2.4 states that ciphertext plus pad_len, next_header fields must 434 // terminate on a 4-byte boundary. Thus, the minimum ciphertext block size is 4 bytes. 435 if (cryptOrAead == null) { return 4; } 436 437 switch (cryptOrAead.getName()) { 438 case IpSecAlgorithm.CRYPT_AES_CBC: 439 return AES_CBC_BLK_SIZE; 440 case IpSecAlgorithm.AUTH_CRYPT_AES_GCM: 441 return AES_GCM_BLK_SIZE; 442 default: 443 throw new IllegalArgumentException( 444 "Blk size unknown for algorithm" + cryptOrAead.getName()); 445 } 446 } 447 448 /** Helper function to calculate expected ESP packet size. */ 449 private int calculateEspPacketSize( 450 int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) { 451 final int ESP_HDRLEN = 4 + 4; // SPI + Seq# 452 final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length 453 payloadLen += cryptIvLength; // Initialization Vector 454 payloadLen += 2; // ESP trailer 455 456 // Align to block size of encryption algorithm 457 payloadLen += (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize; 458 return payloadLen + ESP_HDRLEN + ICV_LEN; 459 } 460 461 public void checkTransform( 462 int protocol, 463 String localAddress, 464 IpSecAlgorithm crypt, 465 IpSecAlgorithm auth, 466 IpSecAlgorithm aead, 467 boolean doUdpEncap, 468 int sendCount, 469 boolean useJavaSockets) 470 throws Exception { 471 StatsChecker.initStatsChecker(); 472 InetAddress local = InetAddress.getByName(localAddress); 473 474 try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket(); 475 IpSecManager.SecurityParameterIndex spi = 476 mISM.allocateSecurityParameterIndex(local)) { 477 478 IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(mContext); 479 if (crypt != null) { 480 transformBuilder.setEncryption(crypt); 481 } 482 if (auth != null) { 483 transformBuilder.setAuthentication(auth); 484 } 485 if (aead != null) { 486 transformBuilder.setAuthenticatedEncryption(aead); 487 } 488 489 if (doUdpEncap) { 490 transformBuilder = 491 transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort()); 492 } 493 494 int ipHdrLen = local instanceof Inet6Address ? IP6_HDRLEN : IP4_HDRLEN; 495 int transportHdrLen = 0; 496 int udpEncapLen = doUdpEncap ? UDP_HDRLEN : 0; 497 498 try (IpSecTransform transform = 499 transformBuilder.buildTransportModeTransform(local, spi)) { 500 if (protocol == IPPROTO_TCP) { 501 transportHdrLen = TCP_HDRLEN_WITH_OPTIONS; 502 checkTcp(transform, local, sendCount, useJavaSockets); 503 } else if (protocol == IPPROTO_UDP) { 504 transportHdrLen = UDP_HDRLEN; 505 506 // TODO: Also check connected udp. 507 checkUnconnectedUdp(transform, local, sendCount, useJavaSockets); 508 } else { 509 throw new IllegalArgumentException("Invalid protocol"); 510 } 511 } 512 513 checkStatsChecker( 514 protocol, 515 ipHdrLen, 516 transportHdrLen, 517 udpEncapLen, 518 sendCount, 519 getIvLen(crypt != null ? crypt : aead), 520 getBlkSize(crypt != null ? crypt : aead), 521 getTruncLenBits(auth != null ? auth : aead)); 522 } 523 } 524 525 private void checkStatsChecker( 526 int protocol, 527 int ipHdrLen, 528 int transportHdrLen, 529 int udpEncapLen, 530 int sendCount, 531 int ivLen, 532 int blkSize, 533 int truncLenBits) 534 throws Exception { 535 536 int innerPacketSize = TEST_DATA.length + transportHdrLen + ipHdrLen; 537 int outerPacketSize = 538 calculateEspPacketSize( 539 TEST_DATA.length + transportHdrLen, ivLen, blkSize, truncLenBits) 540 + udpEncapLen 541 + ipHdrLen; 542 543 int expectedOuterBytes = outerPacketSize * sendCount; 544 int expectedInnerBytes = innerPacketSize * sendCount; 545 int expectedPackets = sendCount; 546 547 // Each run sends two packets, one in each direction. 548 sendCount *= 2; 549 expectedOuterBytes *= 2; 550 expectedInnerBytes *= 2; 551 expectedPackets *= 2; 552 553 // Add TCP ACKs for data packets 554 if (protocol == IPPROTO_TCP) { 555 int encryptedTcpPktSize = 556 calculateEspPacketSize(TCP_HDRLEN_WITH_OPTIONS, ivLen, blkSize, truncLenBits); 557 558 559 // Add data packet ACKs 560 expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount); 561 expectedInnerBytes += (TCP_HDRLEN_WITH_OPTIONS + ipHdrLen) * (sendCount); 562 expectedPackets += sendCount; 563 } 564 565 StatsChecker.waitForNumPackets(expectedPackets); 566 567 // eBPF only counts inner packets, whereas xt_qtaguid counts outer packets. Allow both 568 StatsChecker.assertUidStatsDelta( 569 expectedOuterBytes, 570 expectedPackets, 571 expectedInnerBytes, 572 expectedOuterBytes, 573 expectedPackets); 574 575 // Unreliable at low numbers due to potential interference from other processes. 576 if (sendCount >= 1000) { 577 StatsChecker.assertIfaceStatsDelta( 578 expectedOuterBytes, expectedPackets, expectedOuterBytes, expectedPackets); 579 } 580 } 581 582 private void checkIkePacket( 583 NativeUdpSocket wrappedEncapSocket, InetAddress localAddr) throws Exception { 584 StatsChecker.initStatsChecker(); 585 586 try (NativeUdpSocket remoteSocket = new NativeUdpSocket(getBoundUdpSocket(localAddr))) { 587 588 // Append IKE/ESP header - 4 bytes of SPI, 4 bytes of seq number, all zeroed out 589 // If the first four bytes are zero, assume non-ESP (IKE traffic) 590 byte[] dataWithEspHeader = new byte[TEST_DATA.length + 8]; 591 System.arraycopy(TEST_DATA, 0, dataWithEspHeader, 8, TEST_DATA.length); 592 593 // Send the IKE packet from remoteSocket to wrappedEncapSocket. Since IKE packets 594 // are multiplexed over the socket, we expect them to appear on the encap socket 595 // (as opposed to being decrypted and received on the non-encap socket) 596 remoteSocket.sendTo(dataWithEspHeader, localAddr, wrappedEncapSocket.getPort()); 597 byte[] in = wrappedEncapSocket.receive(); 598 assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in); 599 600 // Also test that the IKE socket can send data out. 601 wrappedEncapSocket.sendTo(dataWithEspHeader, localAddr, remoteSocket.getPort()); 602 in = remoteSocket.receive(); 603 assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in); 604 605 // Calculate expected packet sizes. Always use IPv4 header, since our kernels only 606 // guarantee support of UDP encap on IPv4. 607 int expectedNumPkts = 2; 608 int expectedPacketSize = 609 expectedNumPkts * (dataWithEspHeader.length + UDP_HDRLEN + IP4_HDRLEN); 610 611 StatsChecker.waitForNumPackets(expectedNumPkts); 612 StatsChecker.assertUidStatsDelta( 613 expectedPacketSize, 614 expectedNumPkts, 615 expectedPacketSize, 616 expectedPacketSize, 617 expectedNumPkts); 618 StatsChecker.assertIfaceStatsDelta( 619 expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts); 620 } 621 } 622 623 public void testIkeOverUdpEncapSocket() throws Exception { 624 // IPv6 not supported for UDP-encap-ESP 625 InetAddress local = InetAddress.getByName(IPV4_LOOPBACK); 626 try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { 627 NativeUdpSocket wrappedEncapSocket = 628 new NativeUdpSocket(encapSocket.getFileDescriptor()); 629 checkIkePacket(wrappedEncapSocket, local); 630 631 // Now try with a transform applied to a socket using this Encap socket 632 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 633 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 634 635 try (IpSecManager.SecurityParameterIndex spi = 636 mISM.allocateSecurityParameterIndex(local); 637 IpSecTransform transform = 638 new IpSecTransform.Builder(mContext) 639 .setEncryption(crypt) 640 .setAuthentication(auth) 641 .setIpv4Encapsulation(encapSocket, encapSocket.getPort()) 642 .buildTransportModeTransform(local, spi); 643 JavaUdpSocket localSocket = new JavaUdpSocket(local)) { 644 applyTransformBidirectionally(mISM, transform, localSocket); 645 646 checkIkePacket(wrappedEncapSocket, local); 647 } 648 } 649 } 650 651 // TODO: Check IKE over ESP sockets (IPv4, IPv6) - does this need SOCK_RAW? 652 653 /* TODO: Re-enable these when policy matcher works for reflected packets 654 * 655 * The issue here is that A sends to B, and everything is new; therefore PREROUTING counts 656 * correctly. But it appears that the security path is not cleared afterwards, thus when A 657 * sends an ACK back to B, the policy matcher flags it as a "IPSec" packet. See b/70635417 658 */ 659 660 // public void testInterfaceCountersTcp4() throws Exception { 661 // IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 662 // IpSecAlgorithm auth = new IpSecAlgorithm( 663 // IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 664 // checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1000); 665 // } 666 667 // public void testInterfaceCountersTcp6() throws Exception { 668 // IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 669 // IpSecAlgorithm auth = new IpSecAlgorithm( 670 // IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 671 // checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1000); 672 // } 673 674 // public void testInterfaceCountersTcp4UdpEncap() throws Exception { 675 // IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 676 // IpSecAlgorithm auth = 677 // new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 678 // checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1000); 679 // } 680 681 public void testInterfaceCountersUdp4() throws Exception { 682 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 683 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 684 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1000, false); 685 } 686 687 public void testInterfaceCountersUdp6() throws Exception { 688 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 689 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 690 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1000, false); 691 } 692 693 public void testInterfaceCountersUdp4UdpEncap() throws Exception { 694 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 695 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 696 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1000, false); 697 } 698 699 public void testAesCbcHmacMd5Tcp4() throws Exception { 700 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 701 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 702 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 703 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 704 } 705 706 public void testAesCbcHmacMd5Tcp6() throws Exception { 707 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 708 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 709 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 710 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 711 } 712 713 public void testAesCbcHmacMd5Udp4() throws Exception { 714 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 715 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 716 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 717 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 718 } 719 720 public void testAesCbcHmacMd5Udp6() throws Exception { 721 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 722 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 723 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 724 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 725 } 726 727 public void testAesCbcHmacSha1Tcp4() throws Exception { 728 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 729 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 730 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 731 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 732 } 733 734 public void testAesCbcHmacSha1Tcp6() throws Exception { 735 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 736 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 737 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 738 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 739 } 740 741 public void testAesCbcHmacSha1Udp4() throws Exception { 742 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 743 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 744 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 745 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 746 } 747 748 public void testAesCbcHmacSha1Udp6() throws Exception { 749 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 750 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 751 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 752 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 753 } 754 755 public void testAesCbcHmacSha256Tcp4() throws Exception { 756 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 757 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 758 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 759 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 760 } 761 762 public void testAesCbcHmacSha256Tcp6() throws Exception { 763 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 764 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 765 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 766 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 767 } 768 769 public void testAesCbcHmacSha256Udp4() throws Exception { 770 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 771 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 772 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 773 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 774 } 775 776 public void testAesCbcHmacSha256Udp6() throws Exception { 777 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 778 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 779 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 780 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 781 } 782 783 public void testAesCbcHmacSha384Tcp4() throws Exception { 784 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 785 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 786 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 787 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 788 } 789 790 public void testAesCbcHmacSha384Tcp6() throws Exception { 791 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 792 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 793 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 794 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 795 } 796 797 public void testAesCbcHmacSha384Udp4() throws Exception { 798 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 799 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 800 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 801 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 802 } 803 804 public void testAesCbcHmacSha384Udp6() throws Exception { 805 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 806 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 807 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 808 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 809 } 810 811 public void testAesCbcHmacSha512Tcp4() throws Exception { 812 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 813 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 814 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 815 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 816 } 817 818 public void testAesCbcHmacSha512Tcp6() throws Exception { 819 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 820 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 821 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 822 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 823 } 824 825 public void testAesCbcHmacSha512Udp4() throws Exception { 826 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 827 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 828 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 829 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 830 } 831 832 public void testAesCbcHmacSha512Udp6() throws Exception { 833 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 834 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 835 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 836 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 837 } 838 839 public void testAesGcm64Tcp4() throws Exception { 840 IpSecAlgorithm authCrypt = 841 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 842 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 843 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 844 } 845 846 public void testAesGcm64Tcp6() throws Exception { 847 IpSecAlgorithm authCrypt = 848 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 849 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 850 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 851 } 852 853 public void testAesGcm64Udp4() throws Exception { 854 IpSecAlgorithm authCrypt = 855 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 856 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 857 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 858 } 859 860 public void testAesGcm64Udp6() throws Exception { 861 IpSecAlgorithm authCrypt = 862 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 863 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 864 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 865 } 866 867 public void testAesGcm96Tcp4() throws Exception { 868 IpSecAlgorithm authCrypt = 869 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 870 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 871 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 872 } 873 874 public void testAesGcm96Tcp6() throws Exception { 875 IpSecAlgorithm authCrypt = 876 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 877 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 878 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 879 } 880 881 public void testAesGcm96Udp4() throws Exception { 882 IpSecAlgorithm authCrypt = 883 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 884 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 885 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 886 } 887 888 public void testAesGcm96Udp6() throws Exception { 889 IpSecAlgorithm authCrypt = 890 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 891 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 892 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 893 } 894 895 public void testAesGcm128Tcp4() throws Exception { 896 IpSecAlgorithm authCrypt = 897 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 898 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 899 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 900 } 901 902 public void testAesGcm128Tcp6() throws Exception { 903 IpSecAlgorithm authCrypt = 904 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 905 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 906 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 907 } 908 909 public void testAesGcm128Udp4() throws Exception { 910 IpSecAlgorithm authCrypt = 911 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 912 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 913 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 914 } 915 916 public void testAesGcm128Udp6() throws Exception { 917 IpSecAlgorithm authCrypt = 918 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 919 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 920 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 921 } 922 923 public void testAesCbcHmacMd5Tcp4UdpEncap() throws Exception { 924 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 925 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 926 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 927 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 928 } 929 930 public void testAesCbcHmacMd5Udp4UdpEncap() throws Exception { 931 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 932 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 933 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 934 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 935 } 936 937 public void testAesCbcHmacSha1Tcp4UdpEncap() throws Exception { 938 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 939 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 940 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 941 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 942 } 943 944 public void testAesCbcHmacSha1Udp4UdpEncap() throws Exception { 945 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 946 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 947 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 948 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 949 } 950 951 public void testAesCbcHmacSha256Tcp4UdpEncap() throws Exception { 952 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 953 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 954 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 955 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 956 } 957 958 public void testAesCbcHmacSha256Udp4UdpEncap() throws Exception { 959 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 960 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 961 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 962 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 963 } 964 965 public void testAesCbcHmacSha384Tcp4UdpEncap() throws Exception { 966 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 967 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 968 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 969 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 970 } 971 972 public void testAesCbcHmacSha384Udp4UdpEncap() throws Exception { 973 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 974 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 975 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 976 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 977 } 978 979 public void testAesCbcHmacSha512Tcp4UdpEncap() throws Exception { 980 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 981 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 982 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 983 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 984 } 985 986 public void testAesCbcHmacSha512Udp4UdpEncap() throws Exception { 987 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 988 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 989 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 990 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 991 } 992 993 public void testAesGcm64Tcp4UdpEncap() throws Exception { 994 IpSecAlgorithm authCrypt = 995 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 996 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 997 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 998 } 999 1000 public void testAesGcm64Udp4UdpEncap() throws Exception { 1001 IpSecAlgorithm authCrypt = 1002 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1003 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1004 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1005 } 1006 1007 public void testAesGcm96Tcp4UdpEncap() throws Exception { 1008 IpSecAlgorithm authCrypt = 1009 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1010 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1011 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1012 } 1013 1014 public void testAesGcm96Udp4UdpEncap() throws Exception { 1015 IpSecAlgorithm authCrypt = 1016 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1017 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1018 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1019 } 1020 1021 public void testAesGcm128Tcp4UdpEncap() throws Exception { 1022 IpSecAlgorithm authCrypt = 1023 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1024 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1025 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1026 } 1027 1028 public void testAesGcm128Udp4UdpEncap() throws Exception { 1029 IpSecAlgorithm authCrypt = 1030 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1031 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1032 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1033 } 1034 1035 public void testCryptUdp4() throws Exception { 1036 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1037 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, false); 1038 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, true); 1039 } 1040 1041 public void testAuthUdp4() throws Exception { 1042 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1043 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, false); 1044 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, true); 1045 } 1046 1047 public void testCryptUdp6() throws Exception { 1048 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1049 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, false); 1050 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, true); 1051 } 1052 1053 public void testAuthUdp6() throws Exception { 1054 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1055 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, false); 1056 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, true); 1057 } 1058 1059 public void testCryptTcp4() throws Exception { 1060 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1061 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, false); 1062 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, true); 1063 } 1064 1065 public void testAuthTcp4() throws Exception { 1066 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1067 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, false); 1068 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, true); 1069 } 1070 1071 public void testCryptTcp6() throws Exception { 1072 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1073 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, false); 1074 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, true); 1075 } 1076 1077 public void testAuthTcp6() throws Exception { 1078 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1079 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, false); 1080 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, true); 1081 } 1082 1083 public void testCryptUdp4UdpEncap() throws Exception { 1084 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1085 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, false); 1086 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, true); 1087 } 1088 1089 public void testAuthUdp4UdpEncap() throws Exception { 1090 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1091 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, false); 1092 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, true); 1093 } 1094 1095 public void testCryptTcp4UdpEncap() throws Exception { 1096 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1097 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, false); 1098 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, true); 1099 } 1100 1101 public void testAuthTcp4UdpEncap() throws Exception { 1102 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1103 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, false); 1104 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, true); 1105 } 1106 1107 public void testOpenUdpEncapSocketSpecificPort() throws Exception { 1108 IpSecManager.UdpEncapsulationSocket encapSocket = null; 1109 int port = -1; 1110 for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) { 1111 try { 1112 port = findUnusedPort(); 1113 encapSocket = mISM.openUdpEncapsulationSocket(port); 1114 break; 1115 } catch (ErrnoException e) { 1116 if (e.errno == OsConstants.EADDRINUSE) { 1117 // Someone claimed the port since we called findUnusedPort. 1118 continue; 1119 } 1120 throw e; 1121 } finally { 1122 if (encapSocket != null) { 1123 encapSocket.close(); 1124 } 1125 } 1126 } 1127 1128 if (encapSocket == null) { 1129 fail("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port"); 1130 } 1131 1132 assertTrue("Returned invalid port", encapSocket.getPort() == port); 1133 } 1134 1135 public void testOpenUdpEncapSocketRandomPort() throws Exception { 1136 try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { 1137 assertTrue("Returned invalid port", encapSocket.getPort() != 0); 1138 } 1139 } 1140 } 1141