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 import static com.android.testutils.MiscAsserts.assertThrows; 56 57 import static org.junit.Assert.assertArrayEquals; 58 import static org.junit.Assert.assertEquals; 59 import static org.junit.Assert.assertTrue; 60 import static org.junit.Assert.fail; 61 import static org.junit.Assume.assumeTrue; 62 63 import android.net.IpSecAlgorithm; 64 import android.net.IpSecManager; 65 import android.net.IpSecTransform; 66 import android.net.TrafficStats; 67 import android.os.Build; 68 import android.platform.test.annotations.AppModeFull; 69 import android.system.ErrnoException; 70 import android.system.Os; 71 import android.system.OsConstants; 72 73 import androidx.test.InstrumentationRegistry; 74 import androidx.test.runner.AndroidJUnit4; 75 76 import com.android.testutils.DevSdkIgnoreRule; 77 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 78 79 import org.junit.Rule; 80 import org.junit.Test; 81 import org.junit.runner.RunWith; 82 83 import java.io.FileDescriptor; 84 import java.io.IOException; 85 import java.net.DatagramPacket; 86 import java.net.DatagramSocket; 87 import java.net.Inet6Address; 88 import java.net.InetAddress; 89 import java.util.Arrays; 90 import java.util.HashMap; 91 import java.util.Map; 92 import java.util.Map.Entry; 93 import java.util.Set; 94 95 @RunWith(AndroidJUnit4.class) 96 @AppModeFull(reason = "Socket cannot bind in instant app mode") 97 public class IpSecManagerTest extends IpSecBaseTest { 98 @Rule public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); 99 100 private static final String TAG = IpSecManagerTest.class.getSimpleName(); 101 102 private static final InetAddress GOOGLE_DNS_4 = InetAddress.parseNumericAddress("8.8.8.8"); 103 private static final InetAddress GOOGLE_DNS_6 = 104 InetAddress.parseNumericAddress("2001:4860:4860::8888"); 105 106 private static final InetAddress[] GOOGLE_DNS_LIST = 107 new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6}; 108 109 private static final int DROID_SPI = 0xD1201D; 110 private static final int MAX_PORT_BIND_ATTEMPTS = 10; 111 112 private static final byte[] AEAD_KEY = getKey(288); 113 114 /* 115 * Allocate a random SPI 116 * Allocate a specific SPI using previous randomly created SPI value 117 * Realloc the same SPI that was specifically created (expect SpiUnavailable) 118 * Close SPIs 119 */ 120 @Test testAllocSpi()121 public void testAllocSpi() throws Exception { 122 for (InetAddress addr : GOOGLE_DNS_LIST) { 123 IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null; 124 randomSpi = mISM.allocateSecurityParameterIndex(addr); 125 assertTrue( 126 "Failed to receive a valid SPI", 127 randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); 128 129 droidSpi = mISM.allocateSecurityParameterIndex(addr, DROID_SPI); 130 assertTrue("Failed to allocate specified SPI, " + DROID_SPI, 131 droidSpi.getSpi() == DROID_SPI); 132 133 IpSecManager.SpiUnavailableException expectedException = 134 assertThrows("Duplicate SPI was allowed to be created", 135 IpSecManager.SpiUnavailableException.class, 136 () -> mISM.allocateSecurityParameterIndex(addr, DROID_SPI)); 137 assertEquals(expectedException.getSpi(), droidSpi.getSpi()); 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("TX bytes", ifaceTxBytes, newIfaceTxBytes, expectedTxByteDelta, 417 ERROR_MARGIN_BYTES); 418 assertApproxEquals("RX bytes", ifaceRxBytes, newIfaceRxBytes, expectedRxByteDelta, 419 ERROR_MARGIN_BYTES); 420 assertApproxEquals("TX packets", ifaceTxPackets, newIfaceTxPackets, 421 expectedTxPacketDelta, ERROR_MARGIN_PKTS); 422 assertApproxEquals("RX packets", ifaceRxPackets, newIfaceRxPackets, 423 expectedRxPacketDelta, ERROR_MARGIN_PKTS); 424 } 425 assertApproxEquals( String what, long oldStats, long newStats, int expectedDelta, double errorMargin)426 private static void assertApproxEquals( 427 String what, long oldStats, long newStats, int expectedDelta, double errorMargin) { 428 assertTrue( 429 "Expected at least " + expectedDelta + " " + what 430 + ", got " + (newStats - oldStats), 431 newStats - oldStats >= expectedDelta); 432 assertTrue( 433 "Expected at most " + errorMargin + " * " + expectedDelta + " " + what 434 + ", got " + (newStats - oldStats), 435 newStats - oldStats < (expectedDelta * errorMargin)); 436 } 437 initStatsChecker()438 private static void initStatsChecker() throws Exception { 439 uidTxBytes = TrafficStats.getUidTxBytes(Os.getuid()); 440 uidRxBytes = TrafficStats.getUidRxBytes(Os.getuid()); 441 uidTxPackets = TrafficStats.getUidTxPackets(Os.getuid()); 442 uidRxPackets = TrafficStats.getUidRxPackets(Os.getuid()); 443 444 ifaceTxBytes = TrafficStats.getLoopbackTxBytes(); 445 ifaceRxBytes = TrafficStats.getLoopbackRxBytes(); 446 ifaceTxPackets = TrafficStats.getLoopbackTxPackets(); 447 ifaceRxPackets = TrafficStats.getLoopbackRxPackets(); 448 } 449 } 450 getTruncLenBits(IpSecAlgorithm authOrAead)451 private int getTruncLenBits(IpSecAlgorithm authOrAead) { 452 return authOrAead == null ? 0 : authOrAead.getTruncationLengthBits(); 453 } 454 getIvLen(IpSecAlgorithm cryptOrAead)455 private int getIvLen(IpSecAlgorithm cryptOrAead) { 456 if (cryptOrAead == null) { return 0; } 457 458 switch (cryptOrAead.getName()) { 459 case IpSecAlgorithm.CRYPT_AES_CBC: 460 return AES_CBC_IV_LEN; 461 case IpSecAlgorithm.CRYPT_AES_CTR: 462 return AES_CTR_IV_LEN; 463 case IpSecAlgorithm.AUTH_CRYPT_AES_GCM: 464 return AES_GCM_IV_LEN; 465 case IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305: 466 return CHACHA20_POLY1305_IV_LEN; 467 default: 468 throw new IllegalArgumentException( 469 "IV length unknown for algorithm" + cryptOrAead.getName()); 470 } 471 } 472 getBlkSize(IpSecAlgorithm cryptOrAead)473 private int getBlkSize(IpSecAlgorithm cryptOrAead) { 474 // RFC 4303, section 2.4 states that ciphertext plus pad_len, next_header fields must 475 // terminate on a 4-byte boundary. Thus, the minimum ciphertext block size is 4 bytes. 476 if (cryptOrAead == null) { return 4; } 477 478 switch (cryptOrAead.getName()) { 479 case IpSecAlgorithm.CRYPT_AES_CBC: 480 return AES_CBC_BLK_SIZE; 481 case IpSecAlgorithm.CRYPT_AES_CTR: 482 return AES_CTR_BLK_SIZE; 483 case IpSecAlgorithm.AUTH_CRYPT_AES_GCM: 484 return AES_GCM_BLK_SIZE; 485 case IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305: 486 return CHACHA20_POLY1305_BLK_SIZE; 487 default: 488 throw new IllegalArgumentException( 489 "Blk size unknown for algorithm" + cryptOrAead.getName()); 490 } 491 } 492 checkTransform( int protocol, String localAddress, IpSecAlgorithm crypt, IpSecAlgorithm auth, IpSecAlgorithm aead, boolean doUdpEncap, int sendCount, boolean useJavaSockets)493 public void checkTransform( 494 int protocol, 495 String localAddress, 496 IpSecAlgorithm crypt, 497 IpSecAlgorithm auth, 498 IpSecAlgorithm aead, 499 boolean doUdpEncap, 500 int sendCount, 501 boolean useJavaSockets) 502 throws Exception { 503 StatsChecker.initStatsChecker(); 504 InetAddress local = InetAddress.getByName(localAddress); 505 506 try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket(); 507 IpSecManager.SecurityParameterIndex spi = 508 mISM.allocateSecurityParameterIndex(local)) { 509 510 IpSecTransform.Builder transformBuilder = 511 new IpSecTransform.Builder(InstrumentationRegistry.getContext()); 512 if (crypt != null) { 513 transformBuilder.setEncryption(crypt); 514 } 515 if (auth != null) { 516 transformBuilder.setAuthentication(auth); 517 } 518 if (aead != null) { 519 transformBuilder.setAuthenticatedEncryption(aead); 520 } 521 522 if (doUdpEncap) { 523 transformBuilder = 524 transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort()); 525 } 526 527 int ipHdrLen = local instanceof Inet6Address ? IP6_HDRLEN : IP4_HDRLEN; 528 int transportHdrLen = 0; 529 int udpEncapLen = doUdpEncap ? UDP_HDRLEN : 0; 530 531 try (IpSecTransform transform = 532 transformBuilder.buildTransportModeTransform(local, spi)) { 533 if (protocol == IPPROTO_TCP) { 534 transportHdrLen = TCP_HDRLEN_WITH_TIMESTAMP_OPT; 535 checkTcp(transform, local, sendCount, useJavaSockets); 536 } else if (protocol == IPPROTO_UDP) { 537 transportHdrLen = UDP_HDRLEN; 538 539 // TODO: Also check connected udp. 540 checkUnconnectedUdp(transform, local, sendCount, useJavaSockets); 541 } else { 542 throw new IllegalArgumentException("Invalid protocol"); 543 } 544 } 545 546 checkStatsChecker( 547 protocol, 548 ipHdrLen, 549 transportHdrLen, 550 udpEncapLen, 551 sendCount, 552 getIvLen(crypt != null ? crypt : aead), 553 getBlkSize(crypt != null ? crypt : aead), 554 getTruncLenBits(auth != null ? auth : aead)); 555 } 556 } 557 checkStatsChecker( int protocol, int ipHdrLen, int transportHdrLen, int udpEncapLen, int sendCount, int ivLen, int blkSize, int truncLenBits)558 private void checkStatsChecker( 559 int protocol, 560 int ipHdrLen, 561 int transportHdrLen, 562 int udpEncapLen, 563 int sendCount, 564 int ivLen, 565 int blkSize, 566 int truncLenBits) 567 throws Exception { 568 int innerPacketSize = TEST_DATA.length + transportHdrLen + ipHdrLen; 569 int outerPacketSize = 570 PacketUtils.calculateEspPacketSize( 571 TEST_DATA.length + transportHdrLen, ivLen, blkSize, truncLenBits) 572 + udpEncapLen 573 + ipHdrLen; 574 575 int expectedOuterBytes = outerPacketSize * sendCount; 576 int expectedInnerBytes = innerPacketSize * sendCount; 577 int expectedPackets = sendCount; 578 579 // Each run sends two packets, one in each direction. 580 sendCount *= 2; 581 expectedOuterBytes *= 2; 582 expectedInnerBytes *= 2; 583 expectedPackets *= 2; 584 585 // Add TCP ACKs for data packets 586 if (protocol == IPPROTO_TCP) { 587 int encryptedTcpPktSize = 588 PacketUtils.calculateEspPacketSize( 589 TCP_HDRLEN_WITH_TIMESTAMP_OPT, ivLen, blkSize, truncLenBits); 590 591 // Add data packet ACKs 592 expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount); 593 expectedInnerBytes += (TCP_HDRLEN_WITH_TIMESTAMP_OPT + ipHdrLen) * (sendCount); 594 expectedPackets += sendCount; 595 } 596 597 StatsChecker.waitForNumPackets(expectedPackets); 598 599 // eBPF only counts inner packets, whereas xt_qtaguid counts outer packets. Allow both 600 StatsChecker.assertUidStatsDelta( 601 expectedOuterBytes, 602 expectedPackets, 603 expectedInnerBytes, 604 expectedOuterBytes, 605 expectedPackets); 606 607 // Unreliable at low numbers due to potential interference from other processes. 608 if (sendCount >= 1000) { 609 StatsChecker.assertIfaceStatsDelta( 610 expectedOuterBytes, expectedPackets, expectedOuterBytes, expectedPackets); 611 } 612 } 613 checkIkePacket( NativeUdpSocket wrappedEncapSocket, InetAddress localAddr)614 private void checkIkePacket( 615 NativeUdpSocket wrappedEncapSocket, InetAddress localAddr) throws Exception { 616 StatsChecker.initStatsChecker(); 617 618 try (NativeUdpSocket remoteSocket = new NativeUdpSocket(getBoundUdpSocket(localAddr))) { 619 620 // Append IKE/ESP header - 4 bytes of SPI, 4 bytes of seq number, all zeroed out 621 // If the first four bytes are zero, assume non-ESP (IKE traffic) 622 byte[] dataWithEspHeader = new byte[TEST_DATA.length + 8]; 623 System.arraycopy(TEST_DATA, 0, dataWithEspHeader, 8, TEST_DATA.length); 624 625 // Send the IKE packet from remoteSocket to wrappedEncapSocket. Since IKE packets 626 // are multiplexed over the socket, we expect them to appear on the encap socket 627 // (as opposed to being decrypted and received on the non-encap socket) 628 remoteSocket.sendTo(dataWithEspHeader, localAddr, wrappedEncapSocket.getPort()); 629 byte[] in = wrappedEncapSocket.receive(); 630 assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in); 631 632 // Also test that the IKE socket can send data out. 633 wrappedEncapSocket.sendTo(dataWithEspHeader, localAddr, remoteSocket.getPort()); 634 in = remoteSocket.receive(); 635 assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in); 636 637 // Calculate expected packet sizes. Always use IPv4 header, since our kernels only 638 // guarantee support of UDP encap on IPv4. 639 int expectedNumPkts = 2; 640 int expectedPacketSize = 641 expectedNumPkts * (dataWithEspHeader.length + UDP_HDRLEN + IP4_HDRLEN); 642 643 StatsChecker.waitForNumPackets(expectedNumPkts); 644 StatsChecker.assertUidStatsDelta( 645 expectedPacketSize, 646 expectedNumPkts, 647 expectedPacketSize, 648 expectedPacketSize, 649 expectedNumPkts); 650 StatsChecker.assertIfaceStatsDelta( 651 expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts); 652 } 653 } 654 655 @Test testIkeOverUdpEncapSocket()656 public void testIkeOverUdpEncapSocket() throws Exception { 657 // IPv6 not supported for UDP-encap-ESP 658 InetAddress local = InetAddress.getByName(IPV4_LOOPBACK); 659 try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { 660 NativeUdpSocket wrappedEncapSocket = 661 new NativeUdpSocket(encapSocket.getFileDescriptor()); 662 checkIkePacket(wrappedEncapSocket, local); 663 664 // Now try with a transform applied to a socket using this Encap socket 665 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 666 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 667 668 try (IpSecManager.SecurityParameterIndex spi = 669 mISM.allocateSecurityParameterIndex(local); 670 IpSecTransform transform = 671 new IpSecTransform.Builder(InstrumentationRegistry.getContext()) 672 .setEncryption(crypt) 673 .setAuthentication(auth) 674 .setIpv4Encapsulation(encapSocket, encapSocket.getPort()) 675 .buildTransportModeTransform(local, spi); 676 JavaUdpSocket localSocket = new JavaUdpSocket(local)) { 677 applyTransformBidirectionally(mISM, transform, localSocket); 678 679 checkIkePacket(wrappedEncapSocket, local); 680 } 681 } 682 } 683 684 // TODO: Check IKE over ESP sockets (IPv4, IPv6) - does this need SOCK_RAW? 685 686 /* TODO: Re-enable these when policy matcher works for reflected packets 687 * 688 * The issue here is that A sends to B, and everything is new; therefore PREROUTING counts 689 * correctly. But it appears that the security path is not cleared afterwards, thus when A 690 * sends an ACK back to B, the policy matcher flags it as a "IPSec" packet. See b/70635417 691 */ 692 693 // public void testInterfaceCountersTcp4() throws Exception { 694 // IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 695 // IpSecAlgorithm auth = new IpSecAlgorithm( 696 // IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 697 // checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1000); 698 // } 699 700 // public void testInterfaceCountersTcp6() throws Exception { 701 // IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 702 // IpSecAlgorithm auth = new IpSecAlgorithm( 703 // IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 704 // checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1000); 705 // } 706 707 // public void testInterfaceCountersTcp4UdpEncap() throws Exception { 708 // IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 709 // IpSecAlgorithm auth = 710 // new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 711 // checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1000); 712 // } 713 714 @IgnoreUpTo(Build.VERSION_CODES.R) 715 @Test testGetSupportedAlgorithms()716 public void testGetSupportedAlgorithms() throws Exception { 717 final Map<String, Integer> algoToRequiredMinSdk = new HashMap<>(); 718 algoToRequiredMinSdk.put(CRYPT_AES_CBC, Build.VERSION_CODES.P); 719 algoToRequiredMinSdk.put(AUTH_HMAC_MD5, Build.VERSION_CODES.P); 720 algoToRequiredMinSdk.put(AUTH_HMAC_SHA1, Build.VERSION_CODES.P); 721 algoToRequiredMinSdk.put(AUTH_HMAC_SHA256, Build.VERSION_CODES.P); 722 algoToRequiredMinSdk.put(AUTH_HMAC_SHA384, Build.VERSION_CODES.P); 723 algoToRequiredMinSdk.put(AUTH_HMAC_SHA512, Build.VERSION_CODES.P); 724 algoToRequiredMinSdk.put(AUTH_CRYPT_AES_GCM, Build.VERSION_CODES.P); 725 726 algoToRequiredMinSdk.put(CRYPT_AES_CTR, Build.VERSION_CODES.S); 727 algoToRequiredMinSdk.put(AUTH_AES_CMAC, Build.VERSION_CODES.S); 728 algoToRequiredMinSdk.put(AUTH_AES_XCBC, Build.VERSION_CODES.S); 729 algoToRequiredMinSdk.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.S); 730 731 final Set<String> supportedAlgos = IpSecAlgorithm.getSupportedAlgorithms(); 732 733 // Verify all supported algorithms are valid 734 for (String algo : supportedAlgos) { 735 assertTrue("Found invalid algo " + algo, algoToRequiredMinSdk.keySet().contains(algo)); 736 } 737 738 // Verify all mandatory algorithms are supported 739 for (Entry<String, Integer> entry : algoToRequiredMinSdk.entrySet()) { 740 if (Math.min(getFirstApiLevel(), getVendorApiLevel()) >= entry.getValue()) { 741 assertTrue( 742 "Fail to support " + entry.getKey(), 743 supportedAlgos.contains(entry.getKey())); 744 } 745 } 746 } 747 748 @Test testInterfaceCountersUdp4()749 public void testInterfaceCountersUdp4() throws Exception { 750 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 751 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 752 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1000, false); 753 } 754 755 @Test testInterfaceCountersUdp6()756 public void testInterfaceCountersUdp6() throws Exception { 757 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 758 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 759 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1000, false); 760 } 761 762 @Test testInterfaceCountersUdp4UdpEncap()763 public void testInterfaceCountersUdp4UdpEncap() throws Exception { 764 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 765 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 766 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1000, false); 767 } 768 769 @Test testAesCbcHmacMd5Tcp4()770 public void testAesCbcHmacMd5Tcp4() throws Exception { 771 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 772 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 773 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 774 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 775 } 776 777 @Test testAesCbcHmacMd5Tcp6()778 public void testAesCbcHmacMd5Tcp6() throws Exception { 779 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 780 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 781 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 782 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 783 } 784 785 @Test testAesCbcHmacMd5Udp4()786 public void testAesCbcHmacMd5Udp4() throws Exception { 787 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 788 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 789 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 790 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 791 } 792 793 @Test testAesCbcHmacMd5Udp6()794 public void testAesCbcHmacMd5Udp6() throws Exception { 795 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 796 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 797 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 798 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 799 } 800 801 @Test testAesCbcHmacSha1Tcp4()802 public void testAesCbcHmacSha1Tcp4() throws Exception { 803 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 804 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 805 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 806 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 807 } 808 809 @Test testAesCbcHmacSha1Tcp6()810 public void testAesCbcHmacSha1Tcp6() throws Exception { 811 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 812 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 813 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 814 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 815 } 816 817 @Test testAesCbcHmacSha1Udp4()818 public void testAesCbcHmacSha1Udp4() throws Exception { 819 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 820 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 821 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 822 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 823 } 824 825 @Test testAesCbcHmacSha1Udp6()826 public void testAesCbcHmacSha1Udp6() throws Exception { 827 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 828 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 829 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 830 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 831 } 832 833 @Test testAesCbcHmacSha256Tcp4()834 public void testAesCbcHmacSha256Tcp4() throws Exception { 835 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 836 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 837 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 838 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 839 } 840 841 @Test testAesCbcHmacSha256Tcp6()842 public void testAesCbcHmacSha256Tcp6() throws Exception { 843 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 844 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 845 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 846 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 847 } 848 849 @Test testAesCbcHmacSha256Udp4()850 public void testAesCbcHmacSha256Udp4() throws Exception { 851 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 852 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 853 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 854 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 855 } 856 857 @Test testAesCbcHmacSha256Udp6()858 public void testAesCbcHmacSha256Udp6() throws Exception { 859 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 860 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 861 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 862 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 863 } 864 865 @Test testAesCbcHmacSha384Tcp4()866 public void testAesCbcHmacSha384Tcp4() throws Exception { 867 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 868 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 869 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 870 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 871 } 872 873 @Test testAesCbcHmacSha384Tcp6()874 public void testAesCbcHmacSha384Tcp6() throws Exception { 875 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 876 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 877 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 878 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 879 } 880 881 @Test testAesCbcHmacSha384Udp4()882 public void testAesCbcHmacSha384Udp4() throws Exception { 883 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 884 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 885 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 886 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 887 } 888 889 @Test testAesCbcHmacSha384Udp6()890 public void testAesCbcHmacSha384Udp6() throws Exception { 891 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 892 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 893 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 894 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 895 } 896 897 @Test testAesCbcHmacSha512Tcp4()898 public void testAesCbcHmacSha512Tcp4() throws Exception { 899 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 900 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 901 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 902 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 903 } 904 905 @Test testAesCbcHmacSha512Tcp6()906 public void testAesCbcHmacSha512Tcp6() throws Exception { 907 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 908 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 909 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 910 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 911 } 912 913 @Test testAesCbcHmacSha512Udp4()914 public void testAesCbcHmacSha512Udp4() throws Exception { 915 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 916 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 917 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 918 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 919 } 920 921 @Test testAesCbcHmacSha512Udp6()922 public void testAesCbcHmacSha512Udp6() throws Exception { 923 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 924 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 925 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 926 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 927 } 928 buildCryptAesCtr()929 private static IpSecAlgorithm buildCryptAesCtr() throws Exception { 930 return new IpSecAlgorithm(CRYPT_AES_CTR, getKeyBytes(AES_CTR_KEY_LEN_20)); 931 } 932 buildAuthHmacSha512()933 private static IpSecAlgorithm buildAuthHmacSha512() throws Exception { 934 return new IpSecAlgorithm( 935 AUTH_HMAC_SHA512, getKeyBytes(HMAC_SHA512_KEY_LEN), HMAC_SHA512_ICV_LEN * 8); 936 } 937 938 @Test testAesCtrHmacSha512Tcp4()939 public void testAesCtrHmacSha512Tcp4() throws Exception { 940 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 941 942 final IpSecAlgorithm crypt = buildCryptAesCtr(); 943 final IpSecAlgorithm auth = buildAuthHmacSha512(); 944 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 945 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 946 } 947 948 @Test testAesCtrHmacSha512Tcp6()949 public void testAesCtrHmacSha512Tcp6() throws Exception { 950 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 951 952 final IpSecAlgorithm crypt = buildCryptAesCtr(); 953 final IpSecAlgorithm auth = buildAuthHmacSha512(); 954 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 955 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 956 } 957 958 @Test testAesCtrHmacSha512Udp4()959 public void testAesCtrHmacSha512Udp4() throws Exception { 960 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 961 962 final IpSecAlgorithm crypt = buildCryptAesCtr(); 963 final IpSecAlgorithm auth = buildAuthHmacSha512(); 964 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 965 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 966 } 967 968 @Test testAesCtrHmacSha512Udp6()969 public void testAesCtrHmacSha512Udp6() throws Exception { 970 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 971 972 final IpSecAlgorithm crypt = buildCryptAesCtr(); 973 final IpSecAlgorithm auth = buildAuthHmacSha512(); 974 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 975 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 976 } 977 buildCryptAesCbc()978 private static IpSecAlgorithm buildCryptAesCbc() throws Exception { 979 return new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 980 } 981 buildAuthAesXcbc()982 private static IpSecAlgorithm buildAuthAesXcbc() throws Exception { 983 return new IpSecAlgorithm( 984 AUTH_AES_XCBC, getKeyBytes(AES_XCBC_KEY_LEN), AES_XCBC_ICV_LEN * 8); 985 } 986 buildAuthAesCmac()987 private static IpSecAlgorithm buildAuthAesCmac() throws Exception { 988 return new IpSecAlgorithm( 989 AUTH_AES_CMAC, getKeyBytes(AES_CMAC_KEY_LEN), AES_CMAC_ICV_LEN * 8); 990 } 991 992 @Test testAesCbcAesXCbcTcp4()993 public void testAesCbcAesXCbcTcp4() throws Exception { 994 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 995 996 final IpSecAlgorithm crypt = buildCryptAesCbc(); 997 final IpSecAlgorithm auth = buildAuthAesXcbc(); 998 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 999 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 1000 } 1001 1002 @Test testAesCbcAesXCbcTcp6()1003 public void testAesCbcAesXCbcTcp6() throws Exception { 1004 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1005 1006 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1007 final IpSecAlgorithm auth = buildAuthAesXcbc(); 1008 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 1009 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 1010 } 1011 1012 @Test testAesCbcAesXCbcUdp4()1013 public void testAesCbcAesXCbcUdp4() throws Exception { 1014 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1015 1016 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1017 final IpSecAlgorithm auth = buildAuthAesXcbc(); 1018 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 1019 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 1020 } 1021 1022 @Test testAesCbcAesXCbcUdp6()1023 public void testAesCbcAesXCbcUdp6() throws Exception { 1024 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1025 1026 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1027 final IpSecAlgorithm auth = buildAuthAesXcbc(); 1028 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 1029 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 1030 } 1031 1032 @Test testAesCbcAesCmacTcp4()1033 public void testAesCbcAesCmacTcp4() throws Exception { 1034 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1035 1036 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1037 final IpSecAlgorithm auth = buildAuthAesCmac(); 1038 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 1039 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 1040 } 1041 1042 @Test testAesCbcAesCmacTcp6()1043 public void testAesCbcAesCmacTcp6() throws Exception { 1044 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1045 1046 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1047 final IpSecAlgorithm auth = buildAuthAesCmac(); 1048 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 1049 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 1050 } 1051 1052 @Test testAesCbcAesCmacUdp4()1053 public void testAesCbcAesCmacUdp4() throws Exception { 1054 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1055 1056 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1057 final IpSecAlgorithm auth = buildAuthAesCmac(); 1058 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false); 1059 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); 1060 } 1061 1062 @Test testAesCbcAesCmacUdp6()1063 public void testAesCbcAesCmacUdp6() throws Exception { 1064 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1065 1066 final IpSecAlgorithm crypt = buildCryptAesCbc(); 1067 final IpSecAlgorithm auth = buildAuthAesCmac(); 1068 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false); 1069 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); 1070 } 1071 1072 @Test testAesGcm64Tcp4()1073 public void testAesGcm64Tcp4() throws Exception { 1074 IpSecAlgorithm authCrypt = 1075 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1076 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1077 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1078 } 1079 1080 @Test testAesGcm64Tcp6()1081 public void testAesGcm64Tcp6() throws Exception { 1082 IpSecAlgorithm authCrypt = 1083 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1084 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1085 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1086 } 1087 1088 @Test testAesGcm64Udp4()1089 public void testAesGcm64Udp4() throws Exception { 1090 IpSecAlgorithm authCrypt = 1091 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1092 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1093 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1094 } 1095 1096 @Test testAesGcm64Udp6()1097 public void testAesGcm64Udp6() throws Exception { 1098 IpSecAlgorithm authCrypt = 1099 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1100 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1101 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1102 } 1103 1104 @Test testAesGcm96Tcp4()1105 public void testAesGcm96Tcp4() throws Exception { 1106 IpSecAlgorithm authCrypt = 1107 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1108 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1109 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1110 } 1111 1112 @Test testAesGcm96Tcp6()1113 public void testAesGcm96Tcp6() throws Exception { 1114 IpSecAlgorithm authCrypt = 1115 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1116 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1117 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1118 } 1119 1120 @Test testAesGcm96Udp4()1121 public void testAesGcm96Udp4() throws Exception { 1122 IpSecAlgorithm authCrypt = 1123 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1124 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1125 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1126 } 1127 1128 @Test testAesGcm96Udp6()1129 public void testAesGcm96Udp6() throws Exception { 1130 IpSecAlgorithm authCrypt = 1131 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1132 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1133 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1134 } 1135 1136 @Test testAesGcm128Tcp4()1137 public void testAesGcm128Tcp4() throws Exception { 1138 IpSecAlgorithm authCrypt = 1139 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1140 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1141 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1142 } 1143 1144 @Test testAesGcm128Tcp6()1145 public void testAesGcm128Tcp6() throws Exception { 1146 IpSecAlgorithm authCrypt = 1147 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1148 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1149 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1150 } 1151 1152 @Test testAesGcm128Udp4()1153 public void testAesGcm128Udp4() throws Exception { 1154 IpSecAlgorithm authCrypt = 1155 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1156 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1157 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1158 } 1159 1160 @Test testAesGcm128Udp6()1161 public void testAesGcm128Udp6() throws Exception { 1162 IpSecAlgorithm authCrypt = 1163 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1164 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1165 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1166 } 1167 buildAuthCryptChaCha20Poly1305()1168 private static IpSecAlgorithm buildAuthCryptChaCha20Poly1305() throws Exception { 1169 return new IpSecAlgorithm( 1170 AUTH_CRYPT_CHACHA20_POLY1305, AEAD_KEY, CHACHA20_POLY1305_ICV_LEN * 8); 1171 } 1172 1173 @Test testChaCha20Poly1305Tcp4()1174 public void testChaCha20Poly1305Tcp4() throws Exception { 1175 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1176 1177 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1178 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1179 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1180 } 1181 1182 @Test testChaCha20Poly1305Tcp6()1183 public void testChaCha20Poly1305Tcp6() throws Exception { 1184 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1185 1186 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1187 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1188 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1189 } 1190 1191 @Test testChaCha20Poly1305Udp4()1192 public void testChaCha20Poly1305Udp4() throws Exception { 1193 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1194 1195 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1196 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false); 1197 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); 1198 } 1199 1200 @Test testChaCha20Poly1305Udp6()1201 public void testChaCha20Poly1305Udp6() throws Exception { 1202 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1203 1204 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1205 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false); 1206 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); 1207 } 1208 1209 @Test testAesCbcHmacMd5Tcp4UdpEncap()1210 public void testAesCbcHmacMd5Tcp4UdpEncap() throws Exception { 1211 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1212 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 1213 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1214 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1215 } 1216 1217 @Test testAesCbcHmacMd5Udp4UdpEncap()1218 public void testAesCbcHmacMd5Udp4UdpEncap() throws Exception { 1219 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1220 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); 1221 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1222 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1223 } 1224 1225 @Test testAesCbcHmacSha1Tcp4UdpEncap()1226 public void testAesCbcHmacSha1Tcp4UdpEncap() throws Exception { 1227 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1228 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 1229 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1230 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1231 } 1232 1233 @Test testAesCbcHmacSha1Udp4UdpEncap()1234 public void testAesCbcHmacSha1Udp4UdpEncap() throws Exception { 1235 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1236 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); 1237 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1238 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1239 } 1240 1241 @Test testAesCbcHmacSha256Tcp4UdpEncap()1242 public void testAesCbcHmacSha256Tcp4UdpEncap() throws Exception { 1243 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1244 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1245 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1246 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1247 } 1248 1249 @Test testAesCbcHmacSha256Udp4UdpEncap()1250 public void testAesCbcHmacSha256Udp4UdpEncap() throws Exception { 1251 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1252 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1253 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1254 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1255 } 1256 1257 @Test testAesCbcHmacSha384Tcp4UdpEncap()1258 public void testAesCbcHmacSha384Tcp4UdpEncap() throws Exception { 1259 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1260 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 1261 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1262 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1263 } 1264 1265 @Test testAesCbcHmacSha384Udp4UdpEncap()1266 public void testAesCbcHmacSha384Udp4UdpEncap() throws Exception { 1267 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1268 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); 1269 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1270 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1271 } 1272 1273 @Test testAesCbcHmacSha512Tcp4UdpEncap()1274 public void testAesCbcHmacSha512Tcp4UdpEncap() throws Exception { 1275 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1276 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 1277 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1278 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1279 } 1280 1281 @Test testAesCbcHmacSha512Udp4UdpEncap()1282 public void testAesCbcHmacSha512Udp4UdpEncap() throws Exception { 1283 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1284 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); 1285 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1286 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1287 } 1288 1289 @Test testAesCtrHmacSha512Tcp4UdpEncap()1290 public void testAesCtrHmacSha512Tcp4UdpEncap() throws Exception { 1291 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 1292 1293 final IpSecAlgorithm crypt = buildCryptAesCtr(); 1294 final IpSecAlgorithm auth = buildAuthHmacSha512(); 1295 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1296 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1297 } 1298 1299 @Test testAesCtrHmacSha512Udp4UdpEncap()1300 public void testAesCtrHmacSha512Udp4UdpEncap() throws Exception { 1301 assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR)); 1302 1303 final IpSecAlgorithm crypt = buildCryptAesCtr(); 1304 final IpSecAlgorithm auth = buildAuthHmacSha512(); 1305 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1306 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1307 } 1308 1309 @Test testAesCbcAesXCbcTcp4UdpEncap()1310 public void testAesCbcAesXCbcTcp4UdpEncap() throws Exception { 1311 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1312 1313 final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 1314 final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_XCBC, getKey(128), 96); 1315 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1316 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1317 } 1318 1319 @Test testAesCbcAesXCbcUdp4UdpEncap()1320 public void testAesCbcAesXCbcUdp4UdpEncap() throws Exception { 1321 assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC)); 1322 1323 final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 1324 final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_XCBC, getKey(128), 96); 1325 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1326 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1327 } 1328 1329 @Test testAesCbcAesCmacTcp4UdpEncap()1330 public void testAesCbcAesCmacTcp4UdpEncap() throws Exception { 1331 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1332 1333 final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 1334 final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_CMAC, getKey(128), 96); 1335 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1336 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1337 } 1338 1339 @Test testAesCbcAesCmacUdp4UdpEncap()1340 public void testAesCbcAesCmacUdp4UdpEncap() throws Exception { 1341 assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC)); 1342 1343 final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY); 1344 final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_CMAC, getKey(128), 96); 1345 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false); 1346 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); 1347 } 1348 1349 @Test testAesGcm64Tcp4UdpEncap()1350 public void testAesGcm64Tcp4UdpEncap() throws Exception { 1351 IpSecAlgorithm authCrypt = 1352 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1353 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1354 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1355 } 1356 1357 @Test testAesGcm64Udp4UdpEncap()1358 public void testAesGcm64Udp4UdpEncap() throws Exception { 1359 IpSecAlgorithm authCrypt = 1360 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); 1361 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1362 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1363 } 1364 1365 @Test testAesGcm96Tcp4UdpEncap()1366 public void testAesGcm96Tcp4UdpEncap() throws Exception { 1367 IpSecAlgorithm authCrypt = 1368 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1369 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1370 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1371 } 1372 1373 @Test testAesGcm96Udp4UdpEncap()1374 public void testAesGcm96Udp4UdpEncap() throws Exception { 1375 IpSecAlgorithm authCrypt = 1376 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); 1377 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1378 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1379 } 1380 1381 @Test testAesGcm128Tcp4UdpEncap()1382 public void testAesGcm128Tcp4UdpEncap() throws Exception { 1383 IpSecAlgorithm authCrypt = 1384 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1385 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1386 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1387 } 1388 1389 @Test testAesGcm128Udp4UdpEncap()1390 public void testAesGcm128Udp4UdpEncap() throws Exception { 1391 IpSecAlgorithm authCrypt = 1392 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 1393 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1394 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1395 } 1396 1397 @Test testChaCha20Poly1305Tcp4UdpEncap()1398 public void testChaCha20Poly1305Tcp4UdpEncap() throws Exception { 1399 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1400 1401 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1402 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1403 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1404 } 1405 1406 @Test testChaCha20Poly1305Udp4UdpEncap()1407 public void testChaCha20Poly1305Udp4UdpEncap() throws Exception { 1408 assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305)); 1409 1410 final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305(); 1411 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false); 1412 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); 1413 } 1414 1415 @Test testCryptUdp4()1416 public void testCryptUdp4() throws Exception { 1417 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1418 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, false); 1419 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, true); 1420 } 1421 1422 @Test testAuthUdp4()1423 public void testAuthUdp4() throws Exception { 1424 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1425 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, false); 1426 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, true); 1427 } 1428 1429 @Test testCryptUdp6()1430 public void testCryptUdp6() throws Exception { 1431 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1432 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, false); 1433 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, true); 1434 } 1435 1436 @Test testAuthUdp6()1437 public void testAuthUdp6() throws Exception { 1438 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1439 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, false); 1440 checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, true); 1441 } 1442 1443 @Test testCryptTcp4()1444 public void testCryptTcp4() throws Exception { 1445 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1446 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, false); 1447 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, true); 1448 } 1449 1450 @Test testAuthTcp4()1451 public void testAuthTcp4() throws Exception { 1452 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1453 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, false); 1454 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, true); 1455 } 1456 1457 @Test testCryptTcp6()1458 public void testCryptTcp6() throws Exception { 1459 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1460 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, false); 1461 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, true); 1462 } 1463 1464 @Test testAuthTcp6()1465 public void testAuthTcp6() throws Exception { 1466 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1467 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, false); 1468 checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, true); 1469 } 1470 1471 @Test testCryptUdp4UdpEncap()1472 public void testCryptUdp4UdpEncap() throws Exception { 1473 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1474 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, false); 1475 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, true); 1476 } 1477 1478 @Test testAuthUdp4UdpEncap()1479 public void testAuthUdp4UdpEncap() throws Exception { 1480 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1481 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, false); 1482 checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, true); 1483 } 1484 1485 @Test testCryptTcp4UdpEncap()1486 public void testCryptTcp4UdpEncap() throws Exception { 1487 IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 1488 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, false); 1489 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, true); 1490 } 1491 1492 @Test testAuthTcp4UdpEncap()1493 public void testAuthTcp4UdpEncap() throws Exception { 1494 IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); 1495 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, false); 1496 checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, true); 1497 } 1498 1499 @Test testOpenUdpEncapSocketSpecificPort()1500 public void testOpenUdpEncapSocketSpecificPort() throws Exception { 1501 IpSecManager.UdpEncapsulationSocket encapSocket = null; 1502 int port = -1; 1503 for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) { 1504 try { 1505 port = findUnusedPort(); 1506 encapSocket = mISM.openUdpEncapsulationSocket(port); 1507 break; 1508 } catch (ErrnoException e) { 1509 if (e.errno == OsConstants.EADDRINUSE) { 1510 // Someone claimed the port since we called findUnusedPort. 1511 continue; 1512 } 1513 throw e; 1514 } finally { 1515 if (encapSocket != null) { 1516 encapSocket.close(); 1517 } 1518 } 1519 } 1520 1521 if (encapSocket == null) { 1522 fail("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port"); 1523 } 1524 1525 assertTrue("Returned invalid port", encapSocket.getPort() == port); 1526 } 1527 1528 @Test testOpenUdpEncapSocketRandomPort()1529 public void testOpenUdpEncapSocketRandomPort() throws Exception { 1530 try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { 1531 assertTrue("Returned invalid port", encapSocket.getPort() != 0); 1532 } 1533 } 1534 } 1535