diff --git a/tests/cts/net/jni/Android.mk b/tests/cts/net/jni/Android.mk
index 887e95e..727a44d 100644
--- a/tests/cts/net/jni/Android.mk
+++ b/tests/cts/net/jni/Android.mk
@@ -28,7 +28,7 @@
 LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog
 LOCAL_CXX_STL := libc++_static
 
-LOCAL_CFLAGS := -Wno-unused-parameter
+LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter
 
 include $(BUILD_SHARED_LIBRARY)
 
@@ -37,6 +37,7 @@
 # Don't include this package in any configuration by default.
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := NativeMultinetworkJni.c
+LOCAL_CFLAGS := -Wall -Werror -Wno-format
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog
 LOCAL_CXX_STL := libc++_static
diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c
index 9156504..2fa5291 100644
--- a/tests/cts/net/jni/NativeMultinetworkJni.c
+++ b/tests/cts/net/jni/NativeMultinetworkJni.c
@@ -47,7 +47,7 @@
     const int saved_errno = errno;
     freeaddrinfo(res);
 
-    ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d",
+    ALOGD("android_getaddrinfofornetwork(%" PRIu64 ", %s) returned rval=%d errno=%d",
           handle, kHostname, rval, saved_errno);
     return rval == 0 ? 0 : -saved_errno;
 }
@@ -61,7 +61,7 @@
     errno = 0;
     int rval = android_setprocnetwork(handle);
     const int saved_errno = errno;
-    ALOGD("android_setprocnetwork(%llu) returned rval=%d errno=%d",
+    ALOGD("android_setprocnetwork(%" PRIu64 ") returned rval=%d errno=%d",
           handle, rval, saved_errno);
     return rval == 0 ? 0 : -saved_errno;
 }
@@ -82,7 +82,7 @@
     errno = 0;
     int rval = android_setsocknetwork(handle, fd);
     const int saved_errno = errno;
-    ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d",
+    ALOGD("android_setprocnetwork(%" PRIu64 ", %d) returned rval=%d errno=%d",
           handle, fd, rval, saved_errno);
     close(fd);
     return rval == 0 ? 0 : -saved_errno;
diff --git a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
index 9009c24..7f790fb 100644
--- a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
+++ b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
@@ -15,14 +15,39 @@
  */
 
 #include <arpa/inet.h>
+#include <error.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <string.h>
 #include <sys/socket.h>
+#include <sys/utsname.h>
 
 #include <gtest/gtest.h>
 #include <cutils/qtaguid.h>
 
+int hasQtaguidKernelSupport() {
+    struct utsname buf;
+    int kernel_version_major;
+    int kernel_version_minor;
+
+    int ret = uname(&buf);
+    if (ret) {
+        ret = -errno;
+        return ret;
+    }
+    char dummy;
+    ret = sscanf(buf.release, "%d.%d%c", &kernel_version_major, &kernel_version_minor, &dummy);
+    if (ret < 3)
+        return -EINVAL;
+
+    if ((kernel_version_major == 4 && kernel_version_minor < 9) ||
+        (kernel_version_major < 4)) {
+        return 1;
+    } else {
+        return access("/proc/net/xt_qtaguid/ctrl", F_OK) != -1;
+    }
+}
+
 int getCtrlSkInfo(int tag, uid_t uid, uint64_t* sk_addr, int* ref_cnt) {
     FILE *fp;
     fp = fopen("/proc/net/xt_qtaguid/ctrl", "r");
@@ -70,6 +95,12 @@
 }
 
 TEST (NativeQtaguidTest, close_socket_without_untag) {
+    int res = hasQtaguidKernelSupport();
+    ASSERT_LE(0, res);
+    if (!res) {
+          GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n";
+          return;
+    }
     int sockfd = socket(AF_INET, SOCK_STREAM, 0);
     uid_t uid = getuid();
     int tag = arc4random();
@@ -83,6 +114,12 @@
 }
 
 TEST (NativeQtaguidTest, close_socket_without_untag_ipv6) {
+    int res = hasQtaguidKernelSupport();
+    ASSERT_LE(0, res);
+    if (!res) {
+          GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n";
+          return;
+    }
     int sockfd = socket(AF_INET6, SOCK_STREAM, 0);
     uid_t uid = getuid();
     int tag = arc4random();
@@ -96,12 +133,17 @@
 }
 
 TEST (NativeQtaguidTest, no_socket_addr_leak) {
+    int res = hasQtaguidKernelSupport();
+    ASSERT_LE(0, res);
+    if (!res) {
+          GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n";
+          return;
+    }
   checkNoSocketPointerLeaks(AF_INET);
   checkNoSocketPointerLeaks(AF_INET6);
 }
 
 int main(int argc, char **argv) {
       testing::InitGoogleTest(&argc, argv);
-
       return RUN_ALL_TESTS();
 }
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
new file mode 100644
index 0000000..8e5d256
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts;
+
+import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.IpSecAlgorithm;
+import android.net.IpSecManager;
+import android.net.IpSecTransform;
+import android.net.TrafficStats;
+import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.test.AndroidTestCase;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+public class IpSecManagerTest extends AndroidTestCase {
+
+    private static final String TAG = IpSecManagerTest.class.getSimpleName();
+
+    private IpSecManager mISM;
+
+    private ConnectivityManager mCM;
+
+    private static InetAddress IpAddress(String addrString) {
+        try {
+            return InetAddress.getByName(addrString);
+        } catch (UnknownHostException e) {
+            throw new IllegalArgumentException("Invalid IP address: " + e);
+        }
+    }
+
+    private static final InetAddress GOOGLE_DNS_4 = IpAddress("8.8.8.8");
+    private static final InetAddress GOOGLE_DNS_6 = IpAddress("2001:4860:4860::8888");
+    private static final InetAddress LOOPBACK_4 = IpAddress("127.0.0.1");
+
+    private static final InetAddress[] GOOGLE_DNS_LIST =
+            new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6};
+
+    private static final int DROID_SPI = 0xD1201D;
+    private static final int MAX_PORT_BIND_ATTEMPTS = 10;
+
+    private static final byte[] CRYPT_KEY = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
+    };
+    private static final byte[] AUTH_KEY = {
+        0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
+        0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
+    };
+
+    private static final String IPV4_LOOPBACK = "127.0.0.1";
+    private static final String IPV6_LOOPBACK = "::1";
+    private static final int TCP_HDRLEN_WITH_OPTIONS = 32;
+    private static final int UDP_HDRLEN = 8;
+    private static final int IP4_HDRLEN = 20;
+    private static final int IP6_HDRLEN = 40;
+
+    private static final byte[] TEST_DATA = "Best test data ever!".getBytes();
+
+    // Encryption parameters
+    private static final int AES_CBC_IV_LEN = 16;
+    private static final int AES_CBC_BLK_SIZE = 16;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+        mISM = (IpSecManager) getContext().getSystemService(Context.IPSEC_SERVICE);
+    }
+
+    /*
+     * Allocate a random SPI
+     * Allocate a specific SPI using previous randomly created SPI value
+     * Realloc the same SPI that was specifically created (expect SpiUnavailable)
+     * Close SPIs
+     */
+    public void testAllocSpi() throws Exception {
+        for (InetAddress addr : GOOGLE_DNS_LIST) {
+            IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null;
+            randomSpi = mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, addr);
+            assertTrue(
+                    "Failed to receive a valid SPI",
+                    randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX);
+
+            droidSpi =
+                    mISM.allocateSecurityParameterIndex(
+                            IpSecTransform.DIRECTION_IN, addr, DROID_SPI);
+            assertTrue(
+                    "Failed to allocate specified SPI, " + DROID_SPI,
+                    droidSpi.getSpi() == DROID_SPI);
+
+            try {
+                mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_IN, addr, DROID_SPI);
+                fail("Duplicate SPI was allowed to be created");
+            } catch (IpSecManager.SpiUnavailableException expected) {
+                // This is a success case because we expect a dupe SPI to throw
+            }
+
+            randomSpi.close();
+            droidSpi.close();
+        }
+    }
+
+    private byte[] getAuthKey(int bitLength) {
+        return Arrays.copyOf(AUTH_KEY, bitLength / 8);
+    }
+
+    private static int getDomain(InetAddress address) {
+        int domain;
+        if (address instanceof Inet6Address)
+            domain = OsConstants.AF_INET6;
+        else
+            domain = OsConstants.AF_INET;
+        return domain;
+    }
+
+    /** This function finds an available port */
+    private static int findUnusedPort() throws Exception {
+        // Get an available port.
+        DatagramSocket s = new DatagramSocket();
+        int port = s.getLocalPort();
+        s.close();
+        return port;
+    }
+
+    private static FileDescriptor getBoundUdpSocket(InetAddress address) throws Exception {
+        FileDescriptor sock =
+                Os.socket(getDomain(address), OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP);
+
+        for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) {
+            try {
+                int port = findUnusedPort();
+                Os.bind(sock, address, port);
+                break;
+            } catch (ErrnoException e) {
+                // Someone claimed the port since we called findUnusedPort.
+                if (e.errno == OsConstants.EADDRINUSE) {
+                    if (i == MAX_PORT_BIND_ATTEMPTS - 1) {
+
+                        fail("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port");
+                    }
+                    continue;
+                }
+                throw e.rethrowAsIOException();
+            }
+        }
+        return sock;
+    }
+
+    private void checkUnconnectedUdp(IpSecTransform transform, InetAddress local, int sendCount,
+                                     boolean useJavaSockets) throws Exception {
+        FileDescriptor udpSocket = null;
+        int localPort;
+
+        if (useJavaSockets) {
+            DatagramSocket localSocket = new DatagramSocket(0, local);
+            localSocket.setSoTimeout(500);
+            ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(localSocket);
+
+            localPort = localSocket.getLocalPort();
+            udpSocket = pfd.getFileDescriptor();
+        } else {
+            udpSocket = getBoundUdpSocket(local);
+            localPort = getPort(udpSocket);
+        }
+
+        mISM.applyTransportModeTransform(udpSocket, transform);
+
+        for (int i = 0; i < sendCount; i++) {
+            byte[] in = new byte[TEST_DATA.length];
+            Os.sendto(udpSocket, TEST_DATA, 0, TEST_DATA.length, 0, local, localPort);
+            Os.read(udpSocket, in, 0, in.length);
+            assertArrayEquals("Encapsulated data did not match.", TEST_DATA, in);
+        }
+
+        mISM.removeTransportModeTransform(udpSocket, transform);
+        Os.close(udpSocket);
+    }
+
+    private void checkTcp(IpSecTransform transform, InetAddress local, int sendCount,
+                          boolean useJavaSockets) throws Exception {
+
+        FileDescriptor server = null, client = null;
+
+        if (useJavaSockets) {
+            Socket serverSocket = new Socket();
+            serverSocket.setSoTimeout(500);
+            ParcelFileDescriptor serverPfd = ParcelFileDescriptor.fromSocket(serverSocket);
+            server = serverPfd.getFileDescriptor();
+
+            Socket clientSocket = new Socket();
+            clientSocket.setSoTimeout(500);
+            ParcelFileDescriptor clientPfd = ParcelFileDescriptor.fromSocket(clientSocket);
+            client = clientPfd.getFileDescriptor();
+        } else {
+            final int domain = getDomain(local);
+            server =
+              Os.socket(domain, OsConstants.SOCK_STREAM, IPPROTO_TCP);
+            client =
+              Os.socket(domain, OsConstants.SOCK_STREAM, IPPROTO_TCP);
+        }
+
+        Os.bind(server, local, 0);
+        int port = ((InetSocketAddress) Os.getsockname(server)).getPort();
+
+        mISM.applyTransportModeTransform(client, transform);
+        mISM.applyTransportModeTransform(server, transform);
+
+        Os.listen(server, 10);
+        Os.connect(client, local, port);
+        FileDescriptor accepted = Os.accept(server, null);
+
+        mISM.applyTransportModeTransform(accepted, transform);
+
+        // Wait for TCP handshake packets to be counted
+        StatsChecker.waitForNumPackets(3); // (SYN, SYN+ACK, ACK)
+
+        // Reset StatsChecker, to ignore negotiation overhead.
+        StatsChecker.initStatsChecker();
+        for (int i = 0; i < sendCount; i++) {
+            byte[] in = new byte[TEST_DATA.length];
+
+            Os.write(client, TEST_DATA, 0, TEST_DATA.length);
+            Os.read(accepted, in, 0, in.length);
+            assertArrayEquals("Client-to-server encrypted data did not match.", TEST_DATA, in);
+
+            // Allow for newest data + ack packets to be returned before sending next packet
+            // Also add the number of expected packets in each of the previous runs (4 per run)
+            StatsChecker.waitForNumPackets(2 + (4 * i));
+            in = new byte[TEST_DATA.length];
+
+            Os.write(accepted, TEST_DATA, 0, TEST_DATA.length);
+            Os.read(client, in, 0, in.length);
+            assertArrayEquals("Server-to-client encrypted data did not match.", TEST_DATA, in);
+
+            // Allow for all data + ack packets to be returned before sending next packet
+            // Also add the number of expected packets in each of the previous runs (4 per run)
+            StatsChecker.waitForNumPackets(4 * (i + 1));
+        }
+
+        mISM.removeTransportModeTransform(server, transform);
+        mISM.removeTransportModeTransform(client, transform);
+        mISM.removeTransportModeTransform(accepted, transform);
+
+        Os.close(server);
+        Os.close(client);
+        Os.close(accepted);
+    }
+
+    /*
+     * Alloc outbound SPI
+     * Alloc inbound SPI
+     * Create transport mode transform
+     * open socket
+     * apply transform to socket
+     * send data on socket
+     * release transform
+     * send data (expect exception)
+     */
+    public void testCreateTransform() throws Exception {
+        InetAddress local = LOOPBACK_4;
+        IpSecManager.SecurityParameterIndex outSpi =
+                mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, local);
+
+        IpSecManager.SecurityParameterIndex inSpi =
+                mISM.allocateSecurityParameterIndex(
+                        IpSecTransform.DIRECTION_IN, local, outSpi.getSpi());
+
+        IpSecTransform transform =
+                new IpSecTransform.Builder(mContext)
+                        .setSpi(IpSecTransform.DIRECTION_OUT, outSpi)
+                        .setEncryption(
+                                IpSecTransform.DIRECTION_OUT,
+                                new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+                        .setAuthentication(
+                                IpSecTransform.DIRECTION_OUT,
+                                new IpSecAlgorithm(
+                                        IpSecAlgorithm.AUTH_HMAC_SHA256,
+                                        AUTH_KEY,
+                                        AUTH_KEY.length * 8))
+                        .setSpi(IpSecTransform.DIRECTION_IN, inSpi)
+                        .setEncryption(
+                                IpSecTransform.DIRECTION_IN,
+                                new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+                        .setAuthentication(
+                                IpSecTransform.DIRECTION_IN,
+                                new IpSecAlgorithm(
+                                        IpSecAlgorithm.AUTH_HMAC_SHA256,
+                                        AUTH_KEY,
+                                        CRYPT_KEY.length * 8))
+                        .buildTransportModeTransform(local);
+
+        // Bind localSocket to a random available port.
+        DatagramSocket localSocket = new DatagramSocket(0);
+        int localPort = localSocket.getLocalPort();
+        localSocket.setSoTimeout(500);
+        ParcelFileDescriptor pin = ParcelFileDescriptor.fromDatagramSocket(localSocket);
+        FileDescriptor udpSocket = pin.getFileDescriptor();
+
+        mISM.applyTransportModeTransform(udpSocket, transform);
+        byte[] data = new String("Best test data ever!").getBytes("UTF-8");
+
+        byte[] in = new byte[data.length];
+        Os.sendto(udpSocket, data, 0, data.length, 0, local, localPort);
+        Os.read(udpSocket, in, 0, in.length);
+        assertTrue("Encapsulated data did not match.", Arrays.equals(data, in));
+        mISM.removeTransportModeTransform(udpSocket, transform);
+        Os.close(udpSocket);
+        transform.close();
+    }
+
+    /** Snapshot of TrafficStats as of initStatsChecker call for later comparisons */
+    private static class StatsChecker {
+        private static final String LOOPBACK_INTERFACE = "lo";
+        private static final double ERROR_MARGIN_BYTES = 1.05;
+        private static final double ERROR_MARGIN_PKTS = 1.05;
+        private static final int MAX_WAIT_TIME_MILLIS = 1000;
+
+        private static long uidTxBytes;
+        private static long uidRxBytes;
+        private static long uidTxPackets;
+        private static long uidRxPackets;
+
+        private static long ifaceTxBytes;
+        private static long ifaceRxBytes;
+        private static long ifaceTxPackets;
+        private static long ifaceRxPackets;
+
+        /**
+         * This method counts the number of incoming packets, polling intermittently up to
+         * MAX_WAIT_TIME_MILLIS.
+         */
+        private static void waitForNumPackets(int numPackets) throws Exception {
+            long uidTxDelta = 0;
+            long uidRxDelta = 0;
+            for (int i = 0; i < 100; i++) {
+                uidTxDelta = TrafficStats.getUidTxPackets(Os.getuid()) - uidTxPackets;
+                uidRxDelta = TrafficStats.getUidRxPackets(Os.getuid()) - uidRxPackets;
+
+                // TODO: Check Rx packets as well once kernel security policy bug is fixed.
+                // (b/70635417)
+                if (uidTxDelta >= numPackets) {
+                    return;
+                }
+                Thread.sleep(MAX_WAIT_TIME_MILLIS / 100);
+            }
+            fail(
+                    "Not enough traffic was recorded to satisfy the provided conditions: wanted "
+                            + numPackets
+                            + ", got "
+                            + uidTxDelta
+                            + " tx and "
+                            + uidRxDelta
+                            + " rx packets");
+        }
+
+        private static void assertUidStatsDelta(
+                int expectedTxByteDelta,
+                int expectedTxPacketDelta,
+                int expectedRxByteDelta,
+                int expectedRxPacketDelta) {
+            long newUidTxBytes = TrafficStats.getUidTxBytes(Os.getuid());
+            long newUidRxBytes = TrafficStats.getUidRxBytes(Os.getuid());
+            long newUidTxPackets = TrafficStats.getUidTxPackets(Os.getuid());
+            long newUidRxPackets = TrafficStats.getUidRxPackets(Os.getuid());
+
+            assertEquals(expectedTxByteDelta, newUidTxBytes - uidTxBytes);
+            assertEquals(expectedRxByteDelta, newUidRxBytes - uidRxBytes);
+            assertEquals(expectedTxPacketDelta, newUidTxPackets - uidTxPackets);
+            assertEquals(expectedRxPacketDelta, newUidRxPackets - uidRxPackets);
+        }
+
+        private static void assertIfaceStatsDelta(
+                int expectedTxByteDelta,
+                int expectedTxPacketDelta,
+                int expectedRxByteDelta,
+                int expectedRxPacketDelta)
+                throws IOException {
+            long newIfaceTxBytes = TrafficStats.getLoopbackTxBytes();
+            long newIfaceRxBytes = TrafficStats.getLoopbackRxBytes();
+            long newIfaceTxPackets = TrafficStats.getLoopbackTxPackets();
+            long newIfaceRxPackets = TrafficStats.getLoopbackRxPackets();
+
+            // Check that iface stats are within an acceptable range; data might be sent
+            // on the local interface by other apps.
+            assertApproxEquals(
+                    ifaceTxBytes, newIfaceTxBytes, expectedTxByteDelta, ERROR_MARGIN_BYTES);
+            assertApproxEquals(
+                    ifaceRxBytes, newIfaceRxBytes, expectedRxByteDelta, ERROR_MARGIN_BYTES);
+            assertApproxEquals(
+                    ifaceTxPackets, newIfaceTxPackets, expectedTxPacketDelta, ERROR_MARGIN_PKTS);
+            assertApproxEquals(
+                    ifaceRxPackets, newIfaceRxPackets, expectedRxPacketDelta, ERROR_MARGIN_PKTS);
+        }
+
+        private static void assertApproxEquals(
+                long oldStats, long newStats, int expectedDelta, double errorMargin) {
+            assertTrue(expectedDelta <= newStats - oldStats);
+            assertTrue((expectedDelta * errorMargin) > newStats - oldStats);
+        }
+
+        private static void initStatsChecker() throws IOException {
+            uidTxBytes = TrafficStats.getUidTxBytes(Os.getuid());
+            uidRxBytes = TrafficStats.getUidRxBytes(Os.getuid());
+            uidTxPackets = TrafficStats.getUidTxPackets(Os.getuid());
+            uidRxPackets = TrafficStats.getUidRxPackets(Os.getuid());
+
+            ifaceTxBytes = TrafficStats.getLoopbackTxBytes();
+            ifaceRxBytes = TrafficStats.getLoopbackRxBytes();
+            ifaceTxPackets = TrafficStats.getLoopbackTxPackets();
+            ifaceRxPackets = TrafficStats.getLoopbackRxPackets();
+        }
+    }
+
+    /** Helper function to calculate expected ESP packet size. */
+    private int calculateEspPacketSize(
+            int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) {
+        final int ESP_HDRLEN = 4 + 4; // SPI + Seq#
+        final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length
+        payloadLen += cryptIvLength; // Initialization Vector
+        payloadLen += 2; // ESP trailer
+
+        // Align to block size of encryption algorithm
+        payloadLen += (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize;
+        return payloadLen + ESP_HDRLEN + ICV_LEN;
+    }
+
+    /** Helper function to calculate expected ESP packet size using AES-CBC encryption. */
+    private int calculateAesCbcEspPacketSizeWithAuth(int payloadLen, int authTruncLen) {
+        return calculateEspPacketSize(payloadLen, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, authTruncLen);
+    }
+
+    public void checkTransform(
+            int protocol,
+            String localAddress,
+            IpSecAlgorithm crypt,
+            IpSecAlgorithm auth,
+            boolean doUdpEncap,
+            int sendCount,
+            boolean useJavaSockets)
+            throws Exception {
+        StatsChecker.initStatsChecker();
+        InetAddress local = InetAddress.getByName(localAddress);
+
+        try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
+                IpSecManager.SecurityParameterIndex outSpi =
+                        mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, local);
+                IpSecManager.SecurityParameterIndex inSpi =
+                        mISM.allocateSecurityParameterIndex(
+                                IpSecTransform.DIRECTION_IN, local, outSpi.getSpi())) {
+
+            IpSecTransform.Builder transformBuilder =
+                    new IpSecTransform.Builder(mContext)
+                            .setSpi(IpSecTransform.DIRECTION_OUT, outSpi)
+                            .setEncryption(IpSecTransform.DIRECTION_OUT, crypt)
+                            .setAuthentication(IpSecTransform.DIRECTION_OUT, auth)
+                            .setSpi(IpSecTransform.DIRECTION_IN, inSpi)
+                            .setEncryption(IpSecTransform.DIRECTION_IN, crypt)
+                            .setAuthentication(IpSecTransform.DIRECTION_IN, auth);
+
+            if (doUdpEncap) {
+                transformBuilder =
+                        transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
+            }
+
+            int ipHdrLen = local instanceof Inet6Address ? IP6_HDRLEN : IP4_HDRLEN;
+            int transportHdrLen = 0;
+            int udpEncapLen = doUdpEncap ? UDP_HDRLEN : 0;
+
+            try (IpSecTransform transform = transformBuilder.buildTransportModeTransform(local)) {
+                if (protocol == IPPROTO_TCP) {
+                    transportHdrLen = TCP_HDRLEN_WITH_OPTIONS;
+                    checkTcp(transform, local, sendCount, useJavaSockets);
+                } else if (protocol == IPPROTO_UDP) {
+                    transportHdrLen = UDP_HDRLEN;
+
+                    // TODO: Also check connected udp.
+                    checkUnconnectedUdp(transform, local, sendCount, useJavaSockets);
+                } else {
+                    throw new IllegalArgumentException("Invalid protocol");
+                }
+            }
+
+            checkStatsChecker(
+                    protocol,
+                    ipHdrLen,
+                    transportHdrLen,
+                    udpEncapLen,
+                    sendCount,
+                    auth.getTruncationLengthBits());
+        }
+    }
+
+    private void checkStatsChecker(
+            int protocol,
+            int ipHdrLen,
+            int transportHdrLen,
+            int udpEncapLen,
+            int sendCount,
+            int truncLenBits)
+            throws Exception {
+
+        int innerPacketSize = TEST_DATA.length + transportHdrLen + ipHdrLen;
+        int outerPacketSize =
+                calculateAesCbcEspPacketSizeWithAuth(
+                                TEST_DATA.length + transportHdrLen, truncLenBits)
+                        + udpEncapLen
+                        + ipHdrLen;
+
+        int expectedOuterBytes = outerPacketSize * sendCount;
+        int expectedInnerBytes = innerPacketSize * sendCount;
+        int expectedPackets = sendCount;
+
+        // Add TCP ACKs for data packets
+        if (protocol == IPPROTO_TCP) {
+            int encryptedTcpPktSize =
+                    calculateAesCbcEspPacketSizeWithAuth(TCP_HDRLEN_WITH_OPTIONS, truncLenBits);
+
+                // Each run sends two packets, one in each direction.
+                sendCount *= 2;
+                expectedOuterBytes *= 2;
+                expectedInnerBytes *= 2;
+                expectedPackets *= 2;
+
+                // Add data packet ACKs
+                expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount);
+                expectedInnerBytes += (TCP_HDRLEN_WITH_OPTIONS + ipHdrLen) * (sendCount);
+                expectedPackets += sendCount;
+        }
+
+        StatsChecker.waitForNumPackets(expectedPackets);
+
+        if (udpEncapLen != 0) {
+            StatsChecker.assertUidStatsDelta(
+                    expectedOuterBytes, expectedPackets, expectedOuterBytes, expectedPackets);
+        } else {
+            StatsChecker.assertUidStatsDelta(
+                    expectedOuterBytes, expectedPackets, expectedInnerBytes, expectedPackets);
+        }
+
+        // Unreliable at low numbers due to potential interference from other processes.
+        if (sendCount >= 1000) {
+            StatsChecker.assertIfaceStatsDelta(
+                    expectedOuterBytes, expectedPackets, expectedOuterBytes, expectedPackets);
+        }
+    }
+
+    public void testIkeOverUdpEncapSocket() throws Exception {
+        // IPv6 not supported for UDP-encap-ESP
+        InetAddress local = InetAddress.getByName(IPV4_LOOPBACK);
+        StatsChecker.initStatsChecker();
+
+        try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
+            int localPort = getPort(encapSocket.getSocket());
+
+            // Append ESP header - 4 bytes of SPI, 4 bytes of seq number
+            byte[] dataWithEspHeader = new byte[TEST_DATA.length + 8];
+            System.arraycopy(TEST_DATA, 0, dataWithEspHeader, 8, TEST_DATA.length);
+
+            byte[] in = new byte[dataWithEspHeader.length];
+            Os.sendto(
+                    encapSocket.getSocket(),
+                    dataWithEspHeader,
+                    0,
+                    dataWithEspHeader.length,
+                    0,
+                    local,
+                    localPort);
+            Os.read(encapSocket.getSocket(), in, 0, in.length);
+            assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in);
+
+            int ipHdrLen = local instanceof Inet6Address ? IP6_HDRLEN : IP4_HDRLEN;
+            int expectedPacketSize = dataWithEspHeader.length + UDP_HDRLEN + ipHdrLen;
+            StatsChecker.assertUidStatsDelta(expectedPacketSize, 1, expectedPacketSize, 1);
+            StatsChecker.assertIfaceStatsDelta(expectedPacketSize, 1, expectedPacketSize, 1);
+        }
+    }
+
+    // TODO: Check IKE over ESP sockets (IPv4, IPv6) - does this need SOCK_RAW?
+
+    /* TODO: Re-enable these when policy matcher works for reflected packets
+     *
+     * The issue here is that A sends to B, and everything is new; therefore PREROUTING counts
+     * correctly. But it appears that the security path is not cleared afterwards, thus when A
+     * sends an ACK back to B, the policy matcher flags it as a "IPSec" packet. See b/70635417
+     */
+
+    // public void testInterfaceCountersTcp4() throws Exception {
+    //     IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+    //     IpSecAlgorithm auth = new IpSecAlgorithm(
+    //             IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+    //     checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1000);
+    // }
+
+    // public void testInterfaceCountersTcp6() throws Exception {
+    //     IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+    //     IpSecAlgorithm auth = new IpSecAlgorithm(
+    //             IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+    //     checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1000);
+    // }
+
+    // public void testInterfaceCountersTcp4UdpEncap() throws Exception {
+    //     IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+    //     IpSecAlgorithm auth =
+    //             new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+    //     checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1000);
+    // }
+
+    public void testInterfaceCountersUdp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1000, false);
+    }
+
+    public void testInterfaceCountersUdp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1000, false);
+    }
+
+    public void testInterfaceCountersUdp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1000, false);
+    }
+
+    public void testAesCbcHmacMd5Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacMd5Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacMd5Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacMd5Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(
+                IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+    }
+
+    public void testAesCbcHmacMd5Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testAesCbcHmacMd5Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testAesCbcHmacSha1Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testAesCbcHmacSha1Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testAesCbcHmacSha256Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testAesCbcHmacSha256Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testAesCbcHmacSha384Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testAesCbcHmacSha384Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testAesCbcHmacSha512Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testAesCbcHmacSha512Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+    }
+
+    public void testOpenUdpEncapSocketSpecificPort() throws Exception {
+        IpSecManager.UdpEncapsulationSocket encapSocket = null;
+        int port = -1;
+        for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) {
+            try {
+                port = findUnusedPort();
+                encapSocket = mISM.openUdpEncapsulationSocket(port);
+                break;
+            } catch (ErrnoException e) {
+                if (e.errno == OsConstants.EADDRINUSE) {
+                    // Someone claimed the port since we called findUnusedPort.
+                    continue;
+                }
+                throw e;
+            } finally {
+                if (encapSocket != null) {
+                    encapSocket.close();
+                }
+            }
+        }
+
+        if (encapSocket == null) {
+            fail("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port");
+        }
+
+        assertTrue("Returned invalid port", encapSocket.getPort() == port);
+    }
+
+    public void testOpenUdpEncapSocketRandomPort() throws Exception {
+        try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
+            assertTrue("Returned invalid port", encapSocket.getPort() != 0);
+        }
+    }
+
+    public void testUdpEncapsulation() throws Exception {
+        InetAddress local = LOOPBACK_4;
+
+        // TODO: Refactor to make this more representative of a normal application use case. (use
+        // separate sockets for inbound and outbound)
+        // Create SPIs, UDP encap socket
+        try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
+                IpSecManager.SecurityParameterIndex outSpi =
+                        mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, local);
+                IpSecManager.SecurityParameterIndex inSpi =
+                        mISM.allocateSecurityParameterIndex(
+                                IpSecTransform.DIRECTION_IN, local, outSpi.getSpi());
+                IpSecTransform transform =
+                        buildIpSecTransform(mContext, inSpi, outSpi, encapSocket, local)) {
+
+            // Create user socket, apply transform to it
+            FileDescriptor udpSocket = null;
+            try {
+                udpSocket = getBoundUdpSocket(local);
+                int port = getPort(udpSocket);
+
+                mISM.applyTransportModeTransform(udpSocket, transform);
+
+                // Send an ESP packet from this socket to itself. Since the inbound and
+                // outbound transforms match, we should receive the data we sent.
+                byte[] data = new String("IPSec UDP-encap-ESP test data").getBytes("UTF-8");
+                Os.sendto(udpSocket, data, 0, data.length, 0, local, port);
+                byte[] in = new byte[data.length];
+                Os.read(udpSocket, in, 0, in.length);
+                assertTrue("Encapsulated data did not match.", Arrays.equals(data, in));
+
+                // Send an IKE packet from this socket to itself. IKE packets (SPI of 0)
+                // are not transformed in any way, and should be sent in the clear
+                // We expect this to work too (no inbound transforms)
+                final byte[] header = new byte[] {0, 0, 0, 0};
+                final String message = "Sample IKE Packet";
+                data = (new String(header) + message).getBytes("UTF-8");
+                Os.sendto(
+                        encapSocket.getSocket(),
+                        data,
+                        0,
+                        data.length,
+                        0,
+                        local,
+                        encapSocket.getPort());
+                in = new byte[data.length];
+                Os.read(encapSocket.getSocket(), in, 0, in.length);
+                assertTrue(
+                        "Encap socket was unable to send/receive IKE data",
+                        Arrays.equals(data, in));
+
+                mISM.removeTransportModeTransform(udpSocket, transform);
+            } finally {
+                if (udpSocket != null) {
+                    Os.close(udpSocket);
+                }
+            }
+        }
+    }
+
+    public void testIke() throws Exception {
+        InetAddress local = LOOPBACK_4;
+
+        // TODO: Refactor to make this more representative of a normal application use case. (use
+        // separate sockets for inbound and outbound)
+        try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
+                IpSecManager.SecurityParameterIndex outSpi =
+                        mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, local);
+                IpSecManager.SecurityParameterIndex inSpi =
+                        mISM.allocateSecurityParameterIndex(IpSecTransform.DIRECTION_IN, local);
+                IpSecTransform transform =
+                        buildIpSecTransform(mContext, inSpi, outSpi, encapSocket, local)) {
+
+            // Create user socket, apply transform to it
+            FileDescriptor sock = null;
+
+            try {
+                sock = getBoundUdpSocket(local);
+                int port = getPort(sock);
+
+                mISM.applyTransportModeTransform(sock, transform);
+
+                // TODO: Find a way to set a timeout on the socket, and assert the ESP packet
+                // doesn't make it through. Setting sockopts currently throws EPERM (possibly
+                // because it is owned by a different UID).
+
+                // Send ESP packet from our socket to the encap socket. The SPIs do not
+                // match, and we should expect this packet to be dropped.
+                byte[] header = new byte[] {1, 1, 1, 1};
+                String message = "Sample ESP Packet";
+                byte[] data = (new String(header) + message).getBytes("UTF-8");
+                Os.sendto(sock, data, 0, data.length, 0, local, encapSocket.getPort());
+
+                // Send IKE packet from the encap socket to itself. Since IKE is not
+                // transformed in any way, this should succeed.
+                header = new byte[] {0, 0, 0, 0};
+                message = "Sample IKE Packet";
+                data = (new String(header) + message).getBytes("UTF-8");
+                Os.sendto(
+                        encapSocket.getSocket(),
+                        data,
+                        0,
+                        data.length,
+                        0,
+                        local,
+                        encapSocket.getPort());
+
+                // ESP data should be dropped, due to different input SPI (as opposed to being
+                // readable from the encapSocket)
+                // Thus, only IKE data should be received from the socket.
+                // If the first four bytes are zero, assume non-ESP (IKE) traffic.
+                // Expect an nulled out SPI just as we sent out, without being modified.
+                byte[] in = new byte[4];
+                in[0] = 1; // Make sure the array has to be overwritten to pass
+                Os.read(encapSocket.getSocket(), in, 0, in.length);
+                assertTrue(
+                        "Encap socket received UDP-encap-ESP data despite invalid SPIs",
+                        Arrays.equals(header, in));
+
+                mISM.removeTransportModeTransform(sock, transform);
+            } finally {
+                if (sock != null) {
+                    Os.close(sock);
+                }
+            }
+        }
+    }
+
+    private static IpSecTransform buildIpSecTransform(
+            Context mContext,
+            IpSecManager.SecurityParameterIndex inSpi,
+            IpSecManager.SecurityParameterIndex outSpi,
+            IpSecManager.UdpEncapsulationSocket encapSocket,
+            InetAddress remoteAddr)
+            throws Exception {
+        return new IpSecTransform.Builder(mContext)
+                .setSpi(IpSecTransform.DIRECTION_IN, inSpi)
+                .setSpi(IpSecTransform.DIRECTION_OUT, outSpi)
+                .setEncryption(
+                        IpSecTransform.DIRECTION_IN,
+                        new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+                .setEncryption(
+                        IpSecTransform.DIRECTION_OUT,
+                        new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+                .setAuthentication(
+                        IpSecTransform.DIRECTION_IN,
+                        new IpSecAlgorithm(
+                                IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4))
+                .setAuthentication(
+                        IpSecTransform.DIRECTION_OUT,
+                        new IpSecAlgorithm(
+                                IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4))
+                .setIpv4Encapsulation(encapSocket, encapSocket.getPort())
+                .buildTransportModeTransform(remoteAddr);
+    }
+
+    private static int getPort(FileDescriptor sock) throws Exception {
+        return ((InetSocketAddress) Os.getsockname(sock)).getPort();
+    }
+}
