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.net.IpSecAlgorithm.AUTH_AES_CMAC; 20 import static android.net.IpSecAlgorithm.AUTH_AES_XCBC; 21 import static android.net.IpSecAlgorithm.AUTH_CRYPT_AES_GCM; 22 import static android.net.IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305; 23 import static android.net.IpSecAlgorithm.AUTH_HMAC_MD5; 24 import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA1; 25 import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA256; 26 import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA384; 27 import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512; 28 import static android.net.IpSecAlgorithm.CRYPT_AES_CBC; 29 import static android.net.IpSecAlgorithm.CRYPT_AES_CTR; 30 import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE; 31 import static android.net.cts.PacketUtils.AES_CBC_IV_LEN; 32 import static android.net.cts.PacketUtils.AES_CMAC_ICV_LEN; 33 import static android.net.cts.PacketUtils.AES_CMAC_KEY_LEN; 34 import static android.net.cts.PacketUtils.AES_CTR_BLK_SIZE; 35 import static android.net.cts.PacketUtils.AES_CTR_IV_LEN; 36 import static android.net.cts.PacketUtils.AES_CTR_KEY_LEN_20; 37 import static android.net.cts.PacketUtils.AES_GCM_BLK_SIZE; 38 import static android.net.cts.PacketUtils.AES_GCM_IV_LEN; 39 import static android.net.cts.PacketUtils.AES_XCBC_ICV_LEN; 40 import static android.net.cts.PacketUtils.AES_XCBC_KEY_LEN; 41 import static android.net.cts.PacketUtils.CHACHA20_POLY1305_BLK_SIZE; 42 import static android.net.cts.PacketUtils.CHACHA20_POLY1305_ICV_LEN; 43 import static android.net.cts.PacketUtils.CHACHA20_POLY1305_IV_LEN; 44 import static android.net.cts.PacketUtils.HMAC_SHA512_ICV_LEN; 45 import static android.net.cts.PacketUtils.HMAC_SHA512_KEY_LEN; 46 import static android.net.cts.PacketUtils.IP4_HDRLEN; 47 import static android.net.cts.PacketUtils.IP6_HDRLEN; 48 import static android.net.cts.PacketUtils.TCP_HDRLEN_WITH_TIMESTAMP_OPT; 49 import static android.net.cts.PacketUtils.UDP_HDRLEN; 50 import static android.system.OsConstants.IPPROTO_TCP; 51 import static android.system.OsConstants.IPPROTO_UDP; 52 53 import static com.android.compatibility.common.util.PropertyUtil.getFirstApiLevel; 54 import static com.android.compatibility.common.util.PropertyUtil.getVendorApiLevel; 55 56 import static org.junit.Assert.assertArrayEquals; 57 import static org.junit.Assert.assertEquals; 58 import static org.junit.Assert.assertTrue; 59 import static org.junit.Assert.fail; 60 import static org.junit.Assume.assumeTrue; 61 62 import android.net.IpSecAlgorithm; 63 import android.net.IpSecManager; 64 import android.net.IpSecTransform; 65 import android.net.TrafficStats; 66 import android.os.Build; 67 import android.platform.test.annotations.AppModeFull; 68 import android.system.ErrnoException; 69 import android.system.Os; 70 import android.system.OsConstants; 71 72 import androidx.test.InstrumentationRegistry; 73 import androidx.test.runner.AndroidJUnit4; 74 75 import com.android.testutils.DevSdkIgnoreRule; 76 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 77 78 import org.junit.Rule; 79 import org.junit.Test; 80 import org.junit.runner.RunWith; 81 82 import java.io.FileDescriptor; 83 import java.io.IOException; 84 import java.net.DatagramPacket; 85 import java.net.DatagramSocket; 86 import java.net.Inet6Address; 87 import java.net.InetAddress; 88 import java.util.Arrays; 89 import java.util.HashMap; 90 import java.util.Map; 91 import java.util.Map.Entry; 92 import java.util.Set; 93 94 @RunWith(AndroidJUnit4.class) 95 @AppModeFull(reason = "Socket cannot bind in instant app mode") 96 public class IpSecManagerTest extends IpSecBaseTest { 97 @Rule public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); 98 99 private static final String TAG = IpSecManagerTest.class.getSimpleName(); 100 101 private static final InetAddress GOOGLE_DNS_4 = InetAddress.parseNumericAddress("8.8.8.8"); 102 private static final InetAddress GOOGLE_DNS_6 = 103 InetAddress.parseNumericAddress("2001:4860:4860::8888"); 104 105 private static final InetAddress[] GOOGLE_DNS_LIST = 106 new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6}; 107 108 private static final int DROID_SPI = 0xD1201D; 109 private static final int MAX_PORT_BIND_ATTEMPTS = 10; 110 111 private static final byte[] AEAD_KEY = getKey(288); 112 113 /* 114 * Allocate a random SPI 115 * Allocate a specific SPI using previous randomly created SPI value 116 * Realloc the same SPI that was specifically created (expect SpiUnavailable) 117 * Close SPIs 118 */ 119 @Test testAllocSpi()120 public void testAllocSpi() throws Exception { 121 for (InetAddress addr : GOOGLE_DNS_LIST) { 122 IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null; 123 randomSpi = mISM.allocateSecurityParameterIndex(addr); 124 assertTrue( 125 "Failed to receive a valid SPI", 126 randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); 127 128 droidSpi = mISM.allocateSecurityParameterIndex(addr, DROID_SPI); 129 assertTrue("Failed to allocate specified SPI, " + DROID_SPI, 130 droidSpi.getSpi() == DROID_SPI); 131 132 try { 133 mISM.allocateSecurityParameterIndex(addr, DROID_SPI); 134 fail("Duplicate SPI was allowed to be created"); 135 } catch (IpSecManager.SpiUnavailableException expected) { 136 // This is a success case because we expect a dupe SPI to throw 137 } 138 139 randomSpi.close(); 140 droidSpi.close(); 141 } 142 } 143 144 /** This function finds an available port */ findUnusedPort()145 private static int findUnusedPort() throws Exception { 146 // Get an available port. 147 DatagramSocket s = new DatagramSocket(); 148 int port = s.getLocalPort(); 149 s.close(); 150 return port; 151 } 152 getBoundUdpSocket(InetAddress address)153 private static FileDescriptor getBoundUdpSocket(InetAddress address) throws Exception { 154 FileDescriptor sock = 155 Os.socket(getDomain(address), OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP); 156 157 for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) { 158 try { 159 int port = findUnusedPort(); 160 Os.bind(sock, address, port); 161 break; 162 } catch (ErrnoException e) { 163 // Someone claimed the port since we called findUnusedPort. 164 if (e.errno == OsConstants.EADDRINUSE) { 165 if (i == MAX_PORT_BIND_ATTEMPTS - 1) { 166 167 fail("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port"); 168 } 169 continue; 170 } 171 throw e.rethrowAsIOException(); 172 } 173 } 174 return sock; 175 } 176 checkUnconnectedUdp(IpSecTransform transform, InetAddress local, int sendCount, boolean useJavaSockets)177 private void checkUnconnectedUdp(IpSecTransform transform, InetAddress local, int sendCount, 178 boolean useJavaSockets) throws Exception { 179 GenericUdpSocket sockLeft = null, sockRight = null; 180 if (useJavaSockets) { 181 SocketPair<JavaUdpSocket> sockets = getJavaUdpSocketPair(local, mISM, transform, false); 182 sockLeft = sockets.mLeftSock; 183 sockRight = sockets.mRightSock; 184 } else { 185 SocketPair<NativeUdpSocket> sockets = 186 getNativeUdpSocketPair(local, mISM, transform, false); 187 sockLeft = sockets.mLeftSock; 188 sockRight = sockets.mRightSock; 189 } 190 191 for (int i = 0; i < sendCount; i++) { 192 byte[] in; 193 194 sockLeft.sendTo(TEST_DATA, local, sockRight.getPort()); 195 in = sockRight.receive(); 196 assertArrayEquals("Left-to-right encrypted data did not match.", TEST_DATA, in); 197 198 sockRight.sendTo(TEST_DATA, local, sockLeft.getPort()); 199 in = sockLeft.receive(); 200 assertArrayEquals("Right-to-left encrypted data did not match.", TEST_DATA, in); 201 } 202 203 sockLeft.close(); 204 sockRight.close(); 205 } 206 checkTcp(IpSecTransform transform, InetAddress local, int sendCount, boolean useJavaSockets)207 private void checkTcp(IpSecTransform transform, InetAddress local, int sendCount, 208 boolean useJavaSockets) throws Exception { 209 GenericTcpSocket client = null, accepted = null; 210 if (useJavaSockets) { 211 SocketPair<JavaTcpSocket> sockets = getJavaTcpSocketPair(local, mISM, transform); 212 client = sockets.mLeftSock; 213 accepted = sockets.mRightSock; 214 } else { 215 SocketPair<NativeTcpSocket> sockets = getNativeTcpSocketPair(local, mISM, transform); 216 client = sockets.mLeftSock; 217 accepted = sockets.mRightSock; 218 } 219 220 // Wait for TCP handshake packets to be counted 221 StatsChecker.waitForNumPackets(3); // (SYN, SYN+ACK, ACK) 222 223 // Reset StatsChecker, to ignore negotiation overhead. 224 StatsChecker.initStatsChecker(); 225 for (int i = 0; i < sendCount; i++) { 226 byte[] in; 227 228 client.send(TEST_DATA); 229 in = accepted.receive(); 230 assertArrayEquals("Client-to-server encrypted data did not match.", TEST_DATA, in); 231 232 // Allow for newest data + ack packets to be returned before sending next packet 233 // Also add the number of expected packets in each of the previous runs (4 per run) 234 StatsChecker.waitForNumPackets(2 + (4 * i)); 235 236 accepted.send(TEST_DATA); 237 in = client.receive(); 238 assertArrayEquals("Server-to-client encrypted data did not match.", TEST_DATA, in); 239 240 // Allow for all data + ack packets to be returned before sending next packet 241 // Also add the number of expected packets in each of the previous runs (4 per run) 242 StatsChecker.waitForNumPackets(4 * (i + 1)); 243 } 244 245 // Transforms should not be removed from the sockets, otherwise FIN packets will be sent 246 // unencrypted. 247 // This test also unfortunately happens to rely on a nuance of the cleanup order. By 248 // keeping the policy on the socket, but removing the SA before lingering FIN packets 249 // are sent (at an undetermined later time), the FIN packets are dropped. Without this, 250 // we run into all kinds of headaches trying to test data accounting (unsolicited 251 // packets mysteriously appearing and messing up our counters) 252 // The right way to close sockets is to set SO_LINGER to ensure synchronous closure, 253 // closing the sockets, and then closing the transforms. See documentation for the 254 // Socket or FileDescriptor flavors of applyTransportModeTransform() in IpSecManager 255 // for more details. 256 257 client.close(); 258 accepted.close(); 259 } 260 261 /* 262 * Alloc outbound SPI 263 * Alloc inbound SPI 264 * Create transport mode transform 265 * open socket 266 * apply transform to socket 267 * send data on socket 268 * release transform 269 * send data (expect exception) 270 */ 271 @Test testCreateTransform()272 public void testCreateTransform() throws Exception { 273 InetAddress localAddr = InetAddress.getByName(IPV4_LOOPBACK); 274 IpSecManager.SecurityParameterIndex spi = 275 mISM.allocateSecurityParameterIndex(localAddr); 276 277 IpSecTransform transform = 278 new IpSecTransform.Builder(InstrumentationRegistry.getContext()) 279 .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) 280 .setAuthentication( 281 new IpSecAlgorithm( 282 IpSecAlgorithm.AUTH_HMAC_SHA256, 283 AUTH_KEY, 284 AUTH_KEY.length * 8)) 285 .buildTransportModeTransform(localAddr, spi); 286 287 final boolean [][] applyInApplyOut = { 288 {false, false}, {false, true}, {true, false}, {true,true}}; 289 final byte[] data = new String("Best test data ever!").getBytes("UTF-8"); 290 final DatagramPacket outPacket = new DatagramPacket(data, 0, data.length, localAddr, 0); 291 292 byte[] in = new byte[data.length]; 293 DatagramPacket inPacket = new DatagramPacket(in, in.length); 294 DatagramSocket localSocket; 295 int localPort; 296 297 for(boolean[] io : applyInApplyOut) { 298 boolean applyIn = io[0]; 299 boolean applyOut = io[1]; 300 // Bind localSocket to a random available port. 301 localSocket = new DatagramSocket(0); 302 localPort = localSocket.getLocalPort(); 303 localSocket.setSoTimeout(200); 304 outPacket.setPort(localPort); 305 if (applyIn) { 306 mISM.applyTransportModeTransform( 307 localSocket, IpSecManager.DIRECTION_IN, transform); 308 } 309 if (applyOut) { 310 mISM.applyTransportModeTransform( 311 localSocket, IpSecManager.DIRECTION_OUT, transform); 312 } 313 if (applyIn == applyOut) { 314 localSocket.send(outPacket); 315 localSocket.receive(inPacket); 316 assertTrue("Encapsulated data did not match.", 317 Arrays.equals(outPacket.getData(), inPacket.getData())); 318 mISM.removeTransportModeTransforms(localSocket); 319 localSocket.close(); 320 } else { 321 try { 322 localSocket.send(outPacket); 323 localSocket.receive(inPacket); 324 } catch (IOException e) { 325 continue; 326 } finally { 327 mISM.removeTransportModeTransforms(localSocket); 328 localSocket.close(); 329 } 330 // FIXME: This check is disabled because sockets currently receive data 331 // if there is a valid SA for decryption, even when the input policy is 332 // not applied to a socket. 333 // fail("Data IO should fail on asymmetrical transforms! + Input=" 334 // + applyIn + " Output=" + applyOut); 335 } 336 } 337 transform.close(); 338 } 339 340 /** Snapshot of TrafficStats as of initStatsChecker call for later comparisons */ 341 private static class StatsChecker { 342 private static final double ERROR_MARGIN_BYTES = 1.05; 343 private static final double ERROR_MARGIN_PKTS = 1.05; 344 private static final int MAX_WAIT_TIME_MILLIS = 1000; 345 346 private static long uidTxBytes; 347 private static long uidRxBytes; 348 private static long uidTxPackets; 349 private static long uidRxPackets; 350 351 private static long ifaceTxBytes; 352 private static long ifaceRxBytes; 353 private static long ifaceTxPackets; 354 private static long ifaceRxPackets; 355 356 /** 357 * This method counts the number of incoming packets, polling intermittently up to 358 * MAX_WAIT_TIME_MILLIS. 359 */ waitForNumPackets(int numPackets)360 private static void waitForNumPackets(int numPackets) throws Exception { 361 long uidTxDelta = 0; 362 long uidRxDelta = 0; 363 for (int i = 0; i < 100; i++) { 364 uidTxDelta = TrafficStats.getUidTxPackets(Os.getuid()) - uidTxPackets; 365 uidRxDelta = TrafficStats.getUidRxPackets(Os.getuid()) - uidRxPackets; 366 367 // TODO: Check Rx packets as well once kernel security policy bug is fixed. 368 // (b/70635417) 369 if (uidTxDelta >= numPackets) { 370 return; 371 } 372 Thread.sleep(MAX_WAIT_TIME_MILLIS / 100); 373 } 374 fail( 375 "Not enough traffic was recorded to satisfy the provided conditions: wanted " 376 + numPackets 377 + ", got " 378 + uidTxDelta 379 + " tx and " 380 + uidRxDelta 381 + " rx packets"); 382 } 383 assertUidStatsDelta( int expectedTxByteDelta, int expectedTxPacketDelta, int minRxByteDelta, int maxRxByteDelta, int expectedRxPacketDelta)384 private static void assertUidStatsDelta( 385 int expectedTxByteDelta, 386 int expectedTxPacketDelta, 387 int minRxByteDelta, 388 int maxRxByteDelta, 389 int expectedRxPacketDelta) { 390 long newUidTxBytes = TrafficStats.getUidTxBytes(Os.getuid()); 391 long newUidRxBytes = TrafficStats.getUidRxBytes(Os.getuid()); 392 long newUidTxPackets = TrafficStats.getUidTxPackets(Os.getuid()); 393 long newUidRxPackets = TrafficStats.getUidRxPackets(Os.getuid()); 394 395 assertEquals(expectedTxByteDelta, newUidTxBytes - uidTxBytes); 396 assertTrue( 397 newUidRxBytes - uidRxBytes >= minRxByteDelta 398 && newUidRxBytes - uidRxBytes <= maxRxByteDelta); 399 assertEquals(expectedTxPacketDelta, newUidTxPackets - uidTxPackets); 400 assertEquals(expectedRxPacketDelta, newUidRxPackets - uidRxPackets); 401 } 402 assertIfaceStatsDelta( int expectedTxByteDelta, int expectedTxPacketDelta, int expectedRxByteDelta, int expectedRxPacketDelta)403 private static void assertIfaceStatsDelta( 404 int expectedTxByteDelta, 405 int expectedTxPacketDelta, 406 int expectedRxByteDelta, 407 int expectedRxPacketDelta) 408 throws IOException { 409 long newIfaceTxBytes = TrafficStats.getLoopbackTxBytes(); 410 long newIfaceRxBytes = TrafficStats.getLoopbackRxBytes(); 411 long newIfaceTxPackets = TrafficStats.getLoopbackTxPackets(); 412 long newIfaceRxPackets = TrafficStats.getLoopbackRxPackets(); 413 414 // Check that iface stats are within an acceptable range; data might be sent 415 // on the local interface by other apps. 416 assertApproxEquals( 417 ifaceTxBytes, newIfaceTxBytes, expectedTxByteDelta, ERROR_MARGIN_BYTES); 418 assertApproxEquals( 419 ifaceRxBytes, newIfaceRxBytes, expectedRxByteDelta, ERROR_MARGIN_BYTES); 420 assertApproxEquals( 421 ifaceTxPackets, newIfaceTxPackets, expectedTxPacketDelta, ERROR_MARGIN_PKTS); 422 assertApproxEquals( 423 ifaceRxPackets, newIfaceRxPackets, expectedRxPacketDelta, ERROR_MARGIN_PKTS); 424 } 425 assertApproxEquals( long oldStats, long newStats, int expectedDelta, double errorMargin)426 private static void assertApproxEquals( 427 long oldStats, long newStats, int expectedDelta, double errorMargin) { 428 assertTrue(expectedDelta <= newStats - oldStats); 429 assertTrue((expectedDelta * errorMargin) > newStats - oldStats); 430 } 431 initStatsChecker()432 private static void initStatsChecker() throws Exception { 433 uidTxBytes = TrafficStats.getUidTxBytes(Os.getuid()); 434 uidRxBytes = TrafficStats.getUidRxBytes(Os.getuid()); 435 uidTxPackets = TrafficStats.getUidTxPackets(Os.getuid()); 436 uidRxPackets = TrafficStats.getUidRxPackets(Os.getuid()); 437 438 ifaceTxBytes = TrafficStats.getLoopbackTxBytes(); 439 ifaceRxBytes = TrafficStats.getLoopbackRxBytes(); 440 ifaceTxPackets = TrafficStats.getLoopbackTxPackets(); 441 ifaceRxPackets = TrafficStats.getLoopbackRxPackets(); 442 } 443 } 444 getTruncLenBits(IpSecAlgorithm authOrAead)445 private int getTruncLenBits(IpSecAlgorithm authOrAead) { 446 return authOrAead == null ? 0 : authOrAead.getTruncationLengthBits(); 447 } 448 getIvLen(IpSecAlgorithm cryptOrAead)449 private int getIvLen(IpSecAlgorithm cryptOrAead) { 450 if (cryptOrAead == null) { return 0; } 451 452 switch (cryptOrAead.getName()) { 453 case IpSecAlgorithm.CRYPT_AES_CBC: 454 return AES_CBC_IV_LEN; 455 case IpSecAlgorithm.CRYPT_AES_CTR: 456 return AES_CTR_IV_LEN; 457 case IpSecAlgorithm.AUTH_CRYPT_AES_GCM: 458 return AES_GCM_IV_LEN; 459 case IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305: 460 return CHACHA20_POLY1305_IV_LEN; 461 default: 462 throw new IllegalArgumentException( 463 "IV length unknown for algorithm" + cryptOrAead.getName()); 464 } 465 } 466 getBlkSize(IpSecAlgorithm cryptOrAead)467 private int getBlkSize(IpSecAlgorithm cryptOrAead) { 468 // RFC 4303, section 2.4 states that ciphertext plus pad_len, next_header fields must 469 // terminate on a 4-byte boundary. Thus, the minimum ciphertext block size is 4 bytes. 470 if (cryptOrAead == null) { return 4; } 471 472 switch (cryptOrAead.getName()) { 473 case IpSecAlgorithm.CRYPT_AES_CBC: 474 return AES_CBC_BLK_SIZE; 475 case IpSecAlgorithm.CRYPT_AES_CTR: 476 return AES_CTR_BLK_SIZE; 477 case IpSecAlgorithm.AUTH_CRYPT_AES_GCM: 478 return AES_GCM_BLK_SIZE; 479 case IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305: 480 return CHACHA20_POLY1305_BLK_SIZE; 481 default: 482 throw new IllegalArgumentException( 483 "Blk size unknown for algorithm" + cryptOrAead.getName()); 484 } 485 } 486 checkTransform( int protocol, String localAddress, IpSecAlgorithm crypt, IpSecAlgorithm auth, IpSecAlgorithm aead, boolean doUdpEncap, int sendCount, boolean useJavaSockets)487 public void checkTransform( 488 int protocol, 489 String localAddress, 490 IpSecAlgorithm crypt, 491 IpSecAlgorithm auth, 492 IpSecAlgorithm aead, 493 boolean doUdpEncap, 494 int sendCount, 495 boolean useJavaSockets) 496 throws Exception { 497 StatsChecker.initStatsChecker(); 498 InetAddress local = InetAddress.getByName(localAddress); 499 500 try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket(); 501 IpSecManager.SecurityParameterIndex spi = 502 mISM.allocateSecurityParameterIndex(local)) { 503 504 IpSecTransform.Builder transformBuilder = 505 new IpSecTransform.Builder(InstrumentationRegistry.getContext()); 506 if (crypt != null) { 507 transformBuilder.setEncryption(crypt); 508 } 509 if (auth != null) { 510 transformBuilder.setAuthentication(auth); 511 } 512 if (aead != null) { 513 transformBuilder.setAuthenticatedEncryption(aead); 514 } 515 516 if (doUdpEncap) { 517 transformBuilder = 518 transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort()); 519 } 520 521 int ipHdrLen = local instanceof Inet6Address ? IP6_HDRLEN : IP4_HDRLEN; 522 int transportHdrLen = 0; 523 int udpEncapLen = doUdpEncap ? UDP_HDRLEN : 0; 524 525 try (IpSecTransform transform = 526 transformBuilder.buildTransportModeTransform(local, spi)) { 527 if (protocol == IPPROTO_TCP) { 528 transportHdrLen = TCP_HDRLEN_WITH_TIMESTAMP_OPT; 529 checkTcp(transform, local, sendCount, useJavaSockets); 530 } else if (protocol == IPPROTO_UDP) { 531 transportHdrLen = UDP_HDRLEN; 532 533 // TODO: Also check connected udp. 534 checkUnconnectedUdp(transform, local, sendCount, useJavaSockets); 535 } else { 536 throw new IllegalArgumentException("Invalid protocol"); 537 } 538 } 539 540 checkStatsChecker( 541 protocol, 542 ipHdrLen, 543 transportHdrLen, 544 udpEncapLen, 545 sendCount, 546 getIvLen(crypt != null ? crypt : aead), 547 getBlkSize(crypt != null ? crypt : aead), 548 getTruncLenBits(auth != null ? auth : aead)); 549 } 550 } 551 checkStatsChecker( int protocol, int ipHdrLen, int transportHdrLen, int udpEncapLen, int sendCount, int ivLen, int blkSize, int truncLenBits)552 private void checkStatsChecker( 553 int protocol, 554 int ipHdrLen, 555 int transportHdrLen, 556 int udpEncapLen, 557 int sendCount, 558 int ivLen, 559 int blkSize, 560 int truncLenBits) 561 throws Exception { 562 int innerPacketSize = TEST_DATA.length + transportHdrLen + ipHdrLen; 563 int outerPacketSize = 564 PacketUtils.calculateEspPacketSize( 565 TEST_DATA.length + transportHdrLen, ivLen, blkSize, truncLenBits) 566 + udpEncapLen 567 + ipHdrLen; 568 569 int expectedOuterBytes = outerPacketSize * sendCount; 570 int expectedInnerBytes = innerPacketSize * sendCount; 571 int expectedPackets = sendCount; 572 573 // Each run sends two packets, one in each direction. 574 sendCount *= 2; 575 expectedOuterBytes *= 2; 576 expectedInnerBytes *= 2; 577 expectedPackets *= 2; 578 579 // Add TCP ACKs for data packets 580 if (protocol == IPPROTO_TCP) { 581 int encryptedTcpPktSize = 582 PacketUtils.calculateEspPacketSize( 583 TCP_HDRLEN_WITH_TIMESTAMP_OPT, ivLen, blkSize, truncLenBits); 584 585 // Add data packet ACKs 586 expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount); 587 expectedInnerBytes += (TCP_HDRLEN_WITH_TIMESTAMP_OPT + ipHdrLen) * (sendCount); 588 expectedPackets += sendCount; 589 } 590 591 StatsChecker.waitForNumPackets(expectedPackets); 592 593 // eBPF only counts inner packets, whereas xt_qtaguid counts outer packets. Allow both 594 StatsChecker.assertUidStatsDelta( 595 expectedOuterBytes, 596 expectedPackets, 597 expectedInnerBytes, 598 expectedOuterBytes, 599 expectedPackets); 600 601 // Unreliable at low numbers due to potential interference from other processes. 602 if (sendCount >= 1000) { 603 StatsChecker.assertIfaceStatsDelta( 604 expectedOuterBytes, expectedPackets, expectedOuterBytes, expectedPackets); 605 } 606 } 607 checkIkePacket( NativeUdpSocket wrappedEncapSocket, InetAddress localAddr)608 private void checkIkePacket( 609 NativeUdpSocket wrappedEncapSocket, InetAddress localAddr) throws Exception { 610 StatsChecker.initStatsChecker(); 611 612 try (NativeUdpSocket remoteSocket = new NativeUdpSocket(getBoundUdpSocket(localAddr))) { 613 614 // Append IKE/ESP header - 4 bytes of SPI, 4 bytes of seq number, all zeroed out 615 // If the first four bytes are zero, assume non-ESP (IKE traffic) 616 byte[] dataWithEspHeader = new byte[TEST_DATA.length + 8]; 617 System.arraycopy(TEST_DATA, 0, dataWithEspHeader, 8, TEST_DATA.length); 618 619 // Send the IKE packet from remoteSocket to wrappedEncapSocket. Since IKE packets 620 // are multiplexed over the socket, we expect them to appear on the encap socket 621 // (as opposed to being decrypted and received on the non-encap socket) 622 remoteSocket.sendTo(dataWithEspHeader, localAddr, wrappedEncapSocket.getPort()); 623 byte[] in = wrappedEncapSocket.receive(); 624 assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in); 625 626 // Also test that the IKE socket can send data out. 627 wrappedEncapSocket.sendTo(dataWithEspHeader, localAddr, remoteSocket.getPort()); 628 in = remoteSocket.receive(); 629 assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in); 630 631 // Calculate expected packet sizes. Always use IPv4 header, since our kernels only 632 // guarantee support of UDP encap on IPv4. 633 int expectedNumPkts = 2; 634 int expectedPacketSize = 635 expectedNumPkts * (dataWithEspHeader.length + UDP_HDRLEN + IP4_HDRLEN); 636 637 StatsChecker.waitForNumPackets(expectedNumPkts); 638 StatsChecker.assertUidStatsDelta( 639 expectedPacketSize, 640 expectedNumPkts, 641 expectedPacketSize, 642 expectedPacketSize, 643 expectedNumPkts); 644 StatsChecker.assertIfaceStatsDelta( 645 expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts); 646 } 647 } 648 649 @Test testIkeOverUdpEncapSocket()650 public void testIkeOverUdpEncapSocket() throws Exception { 651 // IPv6 not supported for UDP-encap-ESP 652 InetAddress local = InetAddress.getByName(IPV4_LOOPBACK); 653 try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { 654 NativeUdpSocket wrappedEncapSocket = 655 new NativeUdpSocket(encapSocket.getFileDescriptor()); 656 checkIkePacket(wrappedEncapSocket, local); 657 658 // Now try with a transform applied to a socket using this Encap socket 659 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 660 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 661 662 try (IpSecManager.SecurityParameterIndex spi = 663 mISM.allocateSecurityParameterIndex(local); 664 IpSecTransform transform = 665 new IpSecTransform.Builder(InstrumentationRegistry.getContext()) 666 .setEncryption(crypt) 667 .setAuthentication(auth) 668 .setIpv4Encapsulation(encapSocket, encapSocket.getPort()) 669 .buildTransportModeTransform(local, spi); 670 JavaUdpSocket localSocket = new JavaUdpSocket(local)) { 671 applyTransformBidirectionally(mISM, transform, localSocket); 672 673 checkIkePacket(wrappedEncapSocket, local); 674 } 675 } 676 } 677 678 // TODO: Check IKE over ESP sockets (IPv4, IPv6) - does this need SOCK_RAW? 679 680 /* TODO: Re-enable these when policy matcher works for reflected packets 681 * 682 * The issue here is that A sends to B, and everything is new; therefore PREROUTING counts 683 * correctly. But it appears that the security path is not cleared afterwards, thus when A 684 * sends an ACK back to B, the policy matcher flags it as a "IPSec" packet. See b/70635417 685 */ 686 687 // public void testInterfaceCountersTcp4() throws Exception { 688 // IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 689 // IpSecAlgorithm auth = new IpSecAlgorithm( 690 // IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 691 // checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1000); 692 // } 693 694 // public void testInterfaceCountersTcp6() throws Exception { 695 // IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 696 // IpSecAlgorithm auth = new IpSecAlgorithm( 697 // IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 698 // checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1000); 699 // } 700 701 // public void testInterfaceCountersTcp4UdpEncap() throws Exception { 702 // IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 703 // IpSecAlgorithm auth = 704 // new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 705 // checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1000); 706 // } 707 708 @IgnoreUpTo(Build.VERSION_CODES.R) 709 @Test testGetSupportedAlgorithms()710 public void testGetSupportedAlgorithms() throws Exception { 711 final Map<String, Integer> algoToRequiredMinSdk = new HashMap<>(); 712 algoToRequiredMinSdk.put(CRYPT_AES_CBC, Build.VERSION_CODES.P); 713 algoToRequiredMinSdk.put(AUTH_HMAC_MD5, Build.VERSION_CODES.P); 714 algoToRequiredMinSdk.put(AUTH_HMAC_SHA1, Build.VERSION_CODES.P); 715 algoToRequiredMinSdk.put(AUTH_HMAC_SHA256, Build.VERSION_CODES.P); 716 algoToRequiredMinSdk.put(AUTH_HMAC_SHA384, Build.VERSION_CODES.P); 717 algoToRequiredMinSdk.put(AUTH_HMAC_SHA512, Build.VERSION_CODES.P); 718 algoToRequiredMinSdk.put(AUTH_CRYPT_AES_GCM, Build.VERSION_CODES.P); 719 720 // TODO: b/170424293 Use Build.VERSION_CODES.S when is finalized 721 algoToRequiredMinSdk.put(CRYPT_AES_CTR, Build.VERSION_CODES.R + 1); 722 algoToRequiredMinSdk.put(AUTH_AES_CMAC, Build.VERSION_CODES.R + 1); 723 algoToRequiredMinSdk.put(AUTH_AES_XCBC, Build.VERSION_CODES.R + 1); 724 algoToRequiredMinSdk.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.R + 1); 725 726 final Set<String> supportedAlgos = IpSecAlgorithm.getSupportedAlgorithms(); 727 728 // Verify all supported algorithms are valid 729 for (String algo : supportedAlgos) { 730 assertTrue("Found invalid algo " + algo, algoToRequiredMinSdk.keySet().contains(algo)); 731 } 732 733 // Verify all mandatory algorithms are supported 734 for (Entry<String, Integer> entry : algoToRequiredMinSdk.entrySet()) { 735 if (Math.min(getFirstApiLevel(), getVendorApiLevel()) >= entry.getValue()) { 736 assertTrue( 737 "Fail to support " + entry.getKey(), 738 supportedAlgos.contains(entry.getKey())); 739 } 740 } 741 } 742 743 @Test testInterfaceCountersUdp4()744 public void testInterfaceCountersUdp4() throws Exception { 745 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 746 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 747 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1000, false); 748 } 749 750 @Test testInterfaceCountersUdp6()751 public void testInterfaceCountersUdp6() throws Exception { 752 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 753 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 754 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1000, false); 755 } 756 757 @Test testInterfaceCountersUdp4UdpEncap()758 public void testInterfaceCountersUdp4UdpEncap() throws Exception { 759 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 760 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 761 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1000, false); 762 } 763 764 @Test testAesCbcHmacMd5Tcp4()765 public void testAesCbcHmacMd5Tcp4() throws Exception { 766 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 767 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 768 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 769 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 770 } 771 772 @Test testAesCbcHmacMd5Tcp6()773 public void testAesCbcHmacMd5Tcp6() throws Exception { 774 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 775 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 776 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 777 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 778 } 779 780 @Test testAesCbcHmacMd5Udp4()781 public void testAesCbcHmacMd5Udp4() throws Exception { 782 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 783 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 784 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 785 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 786 } 787 788 @Test testAesCbcHmacMd5Udp6()789 public void testAesCbcHmacMd5Udp6() throws Exception { 790 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 791 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 792 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 793 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 794 } 795 796 @Test testAesCbcHmacSha1Tcp4()797 public void testAesCbcHmacSha1Tcp4() throws Exception { 798 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 799 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 800 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 801 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 802 } 803 804 @Test testAesCbcHmacSha1Tcp6()805 public void testAesCbcHmacSha1Tcp6() throws Exception { 806 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 807 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 808 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 809 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 810 } 811 812 @Test testAesCbcHmacSha1Udp4()813 public void testAesCbcHmacSha1Udp4() throws Exception { 814 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 815 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 816 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 817 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 818 } 819 820 @Test testAesCbcHmacSha1Udp6()821 public void testAesCbcHmacSha1Udp6() throws Exception { 822 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 823 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 824 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 825 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 826 } 827 828 @Test testAesCbcHmacSha256Tcp4()829 public void testAesCbcHmacSha256Tcp4() throws Exception { 830 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 831 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 832 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 833 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 834 } 835 836 @Test testAesCbcHmacSha256Tcp6()837 public void testAesCbcHmacSha256Tcp6() throws Exception { 838 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 839 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 840 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 841 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 842 } 843 844 @Test testAesCbcHmacSha256Udp4()845 public void testAesCbcHmacSha256Udp4() throws Exception { 846 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 847 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 848 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 849 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 850 } 851 852 @Test testAesCbcHmacSha256Udp6()853 public void testAesCbcHmacSha256Udp6() throws Exception { 854 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 855 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 856 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 857 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 858 } 859 860 @Test testAesCbcHmacSha384Tcp4()861 public void testAesCbcHmacSha384Tcp4() throws Exception { 862 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 863 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 864 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 865 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 866 } 867 868 @Test testAesCbcHmacSha384Tcp6()869 public void testAesCbcHmacSha384Tcp6() throws Exception { 870 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 871 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 872 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 873 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 874 } 875 876 @Test testAesCbcHmacSha384Udp4()877 public void testAesCbcHmacSha384Udp4() throws Exception { 878 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 879 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 880 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 881 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 882 } 883 884 @Test testAesCbcHmacSha384Udp6()885 public void testAesCbcHmacSha384Udp6() throws Exception { 886 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 887 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 888 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 889 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 890 } 891 892 @Test testAesCbcHmacSha512Tcp4()893 public void testAesCbcHmacSha512Tcp4() throws Exception { 894 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 895 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 896 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 897 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 898 } 899 900 @Test testAesCbcHmacSha512Tcp6()901 public void testAesCbcHmacSha512Tcp6() throws Exception { 902 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 903 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 904 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 905 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 906 } 907 908 @Test testAesCbcHmacSha512Udp4()909 public void testAesCbcHmacSha512Udp4() throws Exception { 910 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 911 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 912 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 913 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 914 } 915 916 @Test testAesCbcHmacSha512Udp6()917 public void testAesCbcHmacSha512Udp6() throws Exception { 918 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 919 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 920 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 921 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 922 } 923 buildCryptAesCtr()924 private static IpSecAlgorithm buildCryptAesCtr() throws Exception { 925 return new IpSecAlgorithm(CRYPT_AES_CTR, getKeyBytes(AES_CTR_KEY_LEN_20)); 926 } 927 buildAuthHmacSha512()928 private static IpSecAlgorithm buildAuthHmacSha512() throws Exception { 929 return new IpSecAlgorithm( 930 AUTH_HMAC_SHA512, getKeyBytes(HMAC_SHA512_KEY_LEN), HMAC_SHA512_ICV_LEN * 8); 931 } 932 933 @Test testAesCtrHmacSha512Tcp4()934 public void testAesCtrHmacSha512Tcp4() throws Exception { 935 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 936 937 final IpSecAlgorithm crypt = buildCryptAesCtr(); 938 final IpSecAlgorithm auth = buildAuthHmacSha512(); 939 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 940 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 941 } 942 943 @Test testAesCtrHmacSha512Tcp6()944 public void testAesCtrHmacSha512Tcp6() throws Exception { 945 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 946 947 final IpSecAlgorithm crypt = buildCryptAesCtr(); 948 final IpSecAlgorithm auth = buildAuthHmacSha512(); 949 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 950 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 951 } 952 953 @Test testAesCtrHmacSha512Udp4()954 public void testAesCtrHmacSha512Udp4() throws Exception { 955 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 956 957 final IpSecAlgorithm crypt = buildCryptAesCtr(); 958 final IpSecAlgorithm auth = buildAuthHmacSha512(); 959 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 960 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 961 } 962 963 @Test testAesCtrHmacSha512Udp6()964 public void testAesCtrHmacSha512Udp6() throws Exception { 965 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 966 967 final IpSecAlgorithm crypt = buildCryptAesCtr(); 968 final IpSecAlgorithm auth = buildAuthHmacSha512(); 969 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 970 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 971 } 972 buildCryptAesCbc()973 private static IpSecAlgorithm buildCryptAesCbc() throws Exception { 974 return new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 975 } 976 buildAuthAesXcbc()977 private static IpSecAlgorithm buildAuthAesXcbc() throws Exception { 978 return new IpSecAlgorithm( 979 AUTH_AES_XCBC, getKeyBytes(AES_XCBC_KEY_LEN), AES_XCBC_ICV_LEN * 8); 980 } 981 buildAuthAesCmac()982 private static IpSecAlgorithm buildAuthAesCmac() throws Exception { 983 return new IpSecAlgorithm( 984 AUTH_AES_CMAC, getKeyBytes(AES_CMAC_KEY_LEN), AES_CMAC_ICV_LEN * 8); 985 } 986 987 @Test testAesCbcAesXCbcTcp4()988 public void testAesCbcAesXCbcTcp4() throws Exception { 989 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 990 991 final IpSecAlgorithm crypt = buildCryptAesCbc(); 992 final IpSecAlgorithm auth = buildAuthAesXcbc(); 993 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 994 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 995 } 996 997 @Test testAesCbcAesXCbcTcp6()998 public void testAesCbcAesXCbcTcp6() throws Exception { 999 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1000 1001 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1002 final IpSecAlgorithm auth = buildAuthAesXcbc(); 1003 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 1004 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 1005 } 1006 1007 @Test testAesCbcAesXCbcUdp4()1008 public void testAesCbcAesXCbcUdp4() throws Exception { 1009 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1010 1011 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1012 final IpSecAlgorithm auth = buildAuthAesXcbc(); 1013 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 1014 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 1015 } 1016 1017 @Test testAesCbcAesXCbcUdp6()1018 public void testAesCbcAesXCbcUdp6() throws Exception { 1019 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1020 1021 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1022 final IpSecAlgorithm auth = buildAuthAesXcbc(); 1023 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 1024 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 1025 } 1026 1027 @Test testAesCbcAesCmacTcp4()1028 public void testAesCbcAesCmacTcp4() throws Exception { 1029 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1030 1031 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1032 final IpSecAlgorithm auth = buildAuthAesCmac(); 1033 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 1034 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 1035 } 1036 1037 @Test testAesCbcAesCmacTcp6()1038 public void testAesCbcAesCmacTcp6() throws Exception { 1039 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1040 1041 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1042 final IpSecAlgorithm auth = buildAuthAesCmac(); 1043 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 1044 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 1045 } 1046 1047 @Test testAesCbcAesCmacUdp4()1048 public void testAesCbcAesCmacUdp4() throws Exception { 1049 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1050 1051 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1052 final IpSecAlgorithm auth = buildAuthAesCmac(); 1053 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 1054 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 1055 } 1056 1057 @Test testAesCbcAesCmacUdp6()1058 public void testAesCbcAesCmacUdp6() throws Exception { 1059 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1060 1061 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1062 final IpSecAlgorithm auth = buildAuthAesCmac(); 1063 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 1064 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 1065 } 1066 1067 @Test testAesGcm64Tcp4()1068 public void testAesGcm64Tcp4() throws Exception { 1069 IpSecAlgorithm authCrypt = 1070 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1071 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1072 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1073 } 1074 1075 @Test testAesGcm64Tcp6()1076 public void testAesGcm64Tcp6() throws Exception { 1077 IpSecAlgorithm authCrypt = 1078 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1079 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1080 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1081 } 1082 1083 @Test testAesGcm64Udp4()1084 public void testAesGcm64Udp4() throws Exception { 1085 IpSecAlgorithm authCrypt = 1086 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1087 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1088 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1089 } 1090 1091 @Test testAesGcm64Udp6()1092 public void testAesGcm64Udp6() throws Exception { 1093 IpSecAlgorithm authCrypt = 1094 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1095 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1096 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1097 } 1098 1099 @Test testAesGcm96Tcp4()1100 public void testAesGcm96Tcp4() throws Exception { 1101 IpSecAlgorithm authCrypt = 1102 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1103 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1104 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1105 } 1106 1107 @Test testAesGcm96Tcp6()1108 public void testAesGcm96Tcp6() throws Exception { 1109 IpSecAlgorithm authCrypt = 1110 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1111 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1112 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1113 } 1114 1115 @Test testAesGcm96Udp4()1116 public void testAesGcm96Udp4() throws Exception { 1117 IpSecAlgorithm authCrypt = 1118 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1119 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1120 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1121 } 1122 1123 @Test testAesGcm96Udp6()1124 public void testAesGcm96Udp6() throws Exception { 1125 IpSecAlgorithm authCrypt = 1126 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1127 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1128 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1129 } 1130 1131 @Test testAesGcm128Tcp4()1132 public void testAesGcm128Tcp4() throws Exception { 1133 IpSecAlgorithm authCrypt = 1134 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1135 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1136 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1137 } 1138 1139 @Test testAesGcm128Tcp6()1140 public void testAesGcm128Tcp6() throws Exception { 1141 IpSecAlgorithm authCrypt = 1142 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1143 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1144 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1145 } 1146 1147 @Test testAesGcm128Udp4()1148 public void testAesGcm128Udp4() throws Exception { 1149 IpSecAlgorithm authCrypt = 1150 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1151 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1152 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1153 } 1154 1155 @Test testAesGcm128Udp6()1156 public void testAesGcm128Udp6() throws Exception { 1157 IpSecAlgorithm authCrypt = 1158 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1159 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1160 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1161 } 1162 buildAuthCryptChaCha20Poly1305()1163 private static IpSecAlgorithm buildAuthCryptChaCha20Poly1305() throws Exception { 1164 return new IpSecAlgorithm( 1165 AUTH_CRYPT_CHACHA20_POLY1305, AEAD_KEY, CHACHA20_POLY1305_ICV_LEN * 8); 1166 } 1167 1168 @Test testChaCha20Poly1305Tcp4()1169 public void testChaCha20Poly1305Tcp4() throws Exception { 1170 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1171 1172 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1173 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1174 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1175 } 1176 1177 @Test testChaCha20Poly1305Tcp6()1178 public void testChaCha20Poly1305Tcp6() throws Exception { 1179 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1180 1181 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1182 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1183 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1184 } 1185 1186 @Test testChaCha20Poly1305Udp4()1187 public void testChaCha20Poly1305Udp4() throws Exception { 1188 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1189 1190 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1191 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1192 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1193 } 1194 1195 @Test testChaCha20Poly1305Udp6()1196 public void testChaCha20Poly1305Udp6() throws Exception { 1197 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1198 1199 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1200 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1201 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1202 } 1203 1204 @Test testAesCbcHmacMd5Tcp4UdpEncap()1205 public void testAesCbcHmacMd5Tcp4UdpEncap() throws Exception { 1206 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1207 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 1208 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1209 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1210 } 1211 1212 @Test testAesCbcHmacMd5Udp4UdpEncap()1213 public void testAesCbcHmacMd5Udp4UdpEncap() throws Exception { 1214 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1215 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 1216 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1217 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1218 } 1219 1220 @Test testAesCbcHmacSha1Tcp4UdpEncap()1221 public void testAesCbcHmacSha1Tcp4UdpEncap() throws Exception { 1222 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1223 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 1224 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1225 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1226 } 1227 1228 @Test testAesCbcHmacSha1Udp4UdpEncap()1229 public void testAesCbcHmacSha1Udp4UdpEncap() throws Exception { 1230 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1231 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 1232 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1233 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1234 } 1235 1236 @Test testAesCbcHmacSha256Tcp4UdpEncap()1237 public void testAesCbcHmacSha256Tcp4UdpEncap() throws Exception { 1238 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1239 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1240 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1241 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1242 } 1243 1244 @Test testAesCbcHmacSha256Udp4UdpEncap()1245 public void testAesCbcHmacSha256Udp4UdpEncap() throws Exception { 1246 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1247 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1248 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1249 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1250 } 1251 1252 @Test testAesCbcHmacSha384Tcp4UdpEncap()1253 public void testAesCbcHmacSha384Tcp4UdpEncap() throws Exception { 1254 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1255 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 1256 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1257 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1258 } 1259 1260 @Test testAesCbcHmacSha384Udp4UdpEncap()1261 public void testAesCbcHmacSha384Udp4UdpEncap() throws Exception { 1262 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1263 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 1264 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1265 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1266 } 1267 1268 @Test testAesCbcHmacSha512Tcp4UdpEncap()1269 public void testAesCbcHmacSha512Tcp4UdpEncap() throws Exception { 1270 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1271 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 1272 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1273 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1274 } 1275 1276 @Test testAesCbcHmacSha512Udp4UdpEncap()1277 public void testAesCbcHmacSha512Udp4UdpEncap() throws Exception { 1278 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1279 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 1280 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1281 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1282 } 1283 1284 @Test testAesCtrHmacSha512Tcp4UdpEncap()1285 public void testAesCtrHmacSha512Tcp4UdpEncap() throws Exception { 1286 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 1287 1288 final IpSecAlgorithm crypt = buildCryptAesCtr(); 1289 final IpSecAlgorithm auth = buildAuthHmacSha512(); 1290 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1291 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1292 } 1293 1294 @Test testAesCtrHmacSha512Udp4UdpEncap()1295 public void testAesCtrHmacSha512Udp4UdpEncap() throws Exception { 1296 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 1297 1298 final IpSecAlgorithm crypt = buildCryptAesCtr(); 1299 final IpSecAlgorithm auth = buildAuthHmacSha512(); 1300 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1301 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1302 } 1303 1304 @Test testAesCbcAesXCbcTcp4UdpEncap()1305 public void testAesCbcAesXCbcTcp4UdpEncap() throws Exception { 1306 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1307 1308 final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 1309 final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_XCBC, getKey(128), 96); 1310 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1311 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1312 } 1313 1314 @Test testAesCbcAesXCbcUdp4UdpEncap()1315 public void testAesCbcAesXCbcUdp4UdpEncap() throws Exception { 1316 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1317 1318 final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 1319 final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_XCBC, getKey(128), 96); 1320 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1321 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1322 } 1323 1324 @Test testAesCbcAesCmacTcp4UdpEncap()1325 public void testAesCbcAesCmacTcp4UdpEncap() throws Exception { 1326 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1327 1328 final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 1329 final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_CMAC, getKey(128), 96); 1330 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1331 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1332 } 1333 1334 @Test testAesCbcAesCmacUdp4UdpEncap()1335 public void testAesCbcAesCmacUdp4UdpEncap() throws Exception { 1336 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1337 1338 final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 1339 final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_CMAC, getKey(128), 96); 1340 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1341 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1342 } 1343 1344 @Test testAesGcm64Tcp4UdpEncap()1345 public void testAesGcm64Tcp4UdpEncap() throws Exception { 1346 IpSecAlgorithm authCrypt = 1347 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1348 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1349 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1350 } 1351 1352 @Test testAesGcm64Udp4UdpEncap()1353 public void testAesGcm64Udp4UdpEncap() throws Exception { 1354 IpSecAlgorithm authCrypt = 1355 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1356 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1357 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1358 } 1359 1360 @Test testAesGcm96Tcp4UdpEncap()1361 public void testAesGcm96Tcp4UdpEncap() throws Exception { 1362 IpSecAlgorithm authCrypt = 1363 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1364 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1365 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1366 } 1367 1368 @Test testAesGcm96Udp4UdpEncap()1369 public void testAesGcm96Udp4UdpEncap() throws Exception { 1370 IpSecAlgorithm authCrypt = 1371 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1372 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1373 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1374 } 1375 1376 @Test testAesGcm128Tcp4UdpEncap()1377 public void testAesGcm128Tcp4UdpEncap() throws Exception { 1378 IpSecAlgorithm authCrypt = 1379 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1380 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1381 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1382 } 1383 1384 @Test testAesGcm128Udp4UdpEncap()1385 public void testAesGcm128Udp4UdpEncap() throws Exception { 1386 IpSecAlgorithm authCrypt = 1387 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1388 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1389 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1390 } 1391 1392 @Test testChaCha20Poly1305Tcp4UdpEncap()1393 public void testChaCha20Poly1305Tcp4UdpEncap() throws Exception { 1394 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1395 1396 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1397 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1398 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1399 } 1400 1401 @Test testChaCha20Poly1305Udp4UdpEncap()1402 public void testChaCha20Poly1305Udp4UdpEncap() throws Exception { 1403 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1404 1405 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1406 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1407 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1408 } 1409 1410 @Test testCryptUdp4()1411 public void testCryptUdp4() throws Exception { 1412 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1413 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, false); 1414 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, true); 1415 } 1416 1417 @Test testAuthUdp4()1418 public void testAuthUdp4() throws Exception { 1419 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1420 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, false); 1421 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, true); 1422 } 1423 1424 @Test testCryptUdp6()1425 public void testCryptUdp6() throws Exception { 1426 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1427 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, false); 1428 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, true); 1429 } 1430 1431 @Test testAuthUdp6()1432 public void testAuthUdp6() throws Exception { 1433 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1434 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, false); 1435 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, true); 1436 } 1437 1438 @Test testCryptTcp4()1439 public void testCryptTcp4() throws Exception { 1440 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1441 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, false); 1442 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, true); 1443 } 1444 1445 @Test testAuthTcp4()1446 public void testAuthTcp4() throws Exception { 1447 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1448 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, false); 1449 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, true); 1450 } 1451 1452 @Test testCryptTcp6()1453 public void testCryptTcp6() throws Exception { 1454 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1455 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, false); 1456 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, true); 1457 } 1458 1459 @Test testAuthTcp6()1460 public void testAuthTcp6() throws Exception { 1461 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1462 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, false); 1463 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, true); 1464 } 1465 1466 @Test testCryptUdp4UdpEncap()1467 public void testCryptUdp4UdpEncap() throws Exception { 1468 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1469 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, false); 1470 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, true); 1471 } 1472 1473 @Test testAuthUdp4UdpEncap()1474 public void testAuthUdp4UdpEncap() throws Exception { 1475 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1476 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, false); 1477 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, true); 1478 } 1479 1480 @Test testCryptTcp4UdpEncap()1481 public void testCryptTcp4UdpEncap() throws Exception { 1482 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1483 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, false); 1484 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, true); 1485 } 1486 1487 @Test testAuthTcp4UdpEncap()1488 public void testAuthTcp4UdpEncap() throws Exception { 1489 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1490 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, false); 1491 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, true); 1492 } 1493 1494 @Test testOpenUdpEncapSocketSpecificPort()1495 public void testOpenUdpEncapSocketSpecificPort() throws Exception { 1496 IpSecManager.UdpEncapsulationSocket encapSocket = null; 1497 int port = -1; 1498 for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) { 1499 try { 1500 port = findUnusedPort(); 1501 encapSocket = mISM.openUdpEncapsulationSocket(port); 1502 break; 1503 } catch (ErrnoException e) { 1504 if (e.errno == OsConstants.EADDRINUSE) { 1505 // Someone claimed the port since we called findUnusedPort. 1506 continue; 1507 } 1508 throw e; 1509 } finally { 1510 if (encapSocket != null) { 1511 encapSocket.close(); 1512 } 1513 } 1514 } 1515 1516 if (encapSocket == null) { 1517 fail("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port"); 1518 } 1519 1520 assertTrue("Returned invalid port", encapSocket.getPort() == port); 1521 } 1522 1523 @Test testOpenUdpEncapSocketRandomPort()1524 public void testOpenUdpEncapSocketRandomPort() throws Exception { 1525 try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { 1526 assertTrue("Returned invalid port", encapSocket.getPort() != 0); 1527 } 1528 } 1529 } 1530