Add CTS for AES-CMAC

This commit:
  - Verify AES-CMAC is supported in device that first
      launched with SDK beyond R
  - Verify IpSecTransforms can be built with AES-CMAC and
      traffic flows

Bug: 171083832
Test: atest IpSecManagerTest
Test: AES-CMAC tests are manually enabled and verified
Change-Id: I00d1aa475033810a5f60f0e3fc692be87ff62e13
Merged-In: I00d1aa475033810a5f60f0e3fc692be87ff62e13
(cherry picked from commit 0891de63113ef91c2520ab103ae0690564a438a9)
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
index 0fba003..e7e1d67 100644
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
@@ -16,6 +16,7 @@
 
 package android.net.cts;
 
+import static android.net.IpSecAlgorithm.AUTH_AES_CMAC;
 import static android.net.IpSecAlgorithm.AUTH_AES_XCBC;
 import static android.net.IpSecAlgorithm.AUTH_CRYPT_AES_GCM;
 import static android.net.IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305;
@@ -28,6 +29,8 @@
 import static android.net.IpSecAlgorithm.CRYPT_AES_CTR;
 import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE;
 import static android.net.cts.PacketUtils.AES_CBC_IV_LEN;
+import static android.net.cts.PacketUtils.AES_CMAC_ICV_LEN;
+import static android.net.cts.PacketUtils.AES_CMAC_KEY_LEN;
 import static android.net.cts.PacketUtils.AES_CTR_BLK_SIZE;
 import static android.net.cts.PacketUtils.AES_CTR_IV_LEN;
 import static android.net.cts.PacketUtils.AES_CTR_KEY_LEN;
@@ -717,6 +720,7 @@
 
         // TODO: b/170424293 Use Build.VERSION_CODES.S when is finalized
         algoToRequiredMinSdk.put(CRYPT_AES_CTR, Build.VERSION_CODES.R + 1);
+        algoToRequiredMinSdk.put(AUTH_AES_CMAC, Build.VERSION_CODES.R + 1);
         algoToRequiredMinSdk.put(AUTH_AES_XCBC, Build.VERSION_CODES.R + 1);
         algoToRequiredMinSdk.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.R + 1);
 
@@ -982,6 +986,11 @@
                 AUTH_AES_XCBC, getKeyBytes(AES_XCBC_KEY_LEN), AES_XCBC_ICV_LEN * 8);
     }
 
+    private static IpSecAlgorithm buildAuthAesCmac() throws Exception {
+        return new IpSecAlgorithm(
+                AUTH_AES_CMAC, getKeyBytes(AES_CMAC_KEY_LEN), AES_CMAC_ICV_LEN * 8);
+    }
+
     @Test
     public void testAesCbcAesXCbcTcp4() throws Exception {
         assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC));
@@ -1024,6 +1033,47 @@
     }
 
     @Test
+    public void testAesCbcAesCmacTcp4() throws Exception {
+        assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+        final IpSecAlgorithm crypt = buildCryptAesCbc();
+        final IpSecAlgorithm auth = buildAuthAesCmac();
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    @Test
+    @SkipPresubmit(reason = "b/186608065 - kernel 5.10 regression in TrafficStats with ipsec")
+    public void testAesCbcAesCmacTcp6() throws Exception {
+        assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+        final IpSecAlgorithm crypt = buildCryptAesCbc();
+        final IpSecAlgorithm auth = buildAuthAesCmac();
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    @Test
+    public void testAesCbcAesCmacUdp4() throws Exception {
+        assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+        final IpSecAlgorithm crypt = buildCryptAesCbc();
+        final IpSecAlgorithm auth = buildAuthAesCmac();
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    @Test
+    public void testAesCbcAesCmacUdp6() throws Exception {
+        assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+        final IpSecAlgorithm crypt = buildCryptAesCbc();
+        final IpSecAlgorithm auth = buildAuthAesCmac();
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    @Test
     public void testAesGcm64Tcp4() throws Exception {
         IpSecAlgorithm authCrypt =
                 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
@@ -1285,6 +1335,26 @@
     }
 
     @Test
+    public void testAesCbcAesCmacTcp4UdpEncap() throws Exception {
+        assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+        final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY);
+        final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_CMAC, getKey(128), 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    @Test
+    public void testAesCbcAesCmacUdp4UdpEncap() throws Exception {
+        assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+        final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY);
+        final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_CMAC, getKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    @Test
     public void testAesGcm64Tcp4UdpEncap() throws Exception {
         IpSecAlgorithm authCrypt =
                 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
diff --git a/tests/cts/net/src/android/net/cts/PacketUtils.java b/tests/cts/net/src/android/net/cts/PacketUtils.java
index 54a70d0..7e622f6 100644
--- a/tests/cts/net/src/android/net/cts/PacketUtils.java
+++ b/tests/cts/net/src/android/net/cts/PacketUtils.java
@@ -69,6 +69,8 @@
     static final int HMAC_SHA512_ICV_LEN = 32;
     static final int AES_XCBC_KEY_LEN = 16;
     static final int AES_XCBC_ICV_LEN = 12;
+    static final int AES_CMAC_KEY_LEN = 16;
+    static final int AES_CMAC_ICV_LEN = 12;
 
     // Encryption algorithms
     static final String AES = "AES";