Merge "Add support for AES-GCM-ESP as an IPSec algorithm"

This commit is contained in:
Benedict Wong
2017-10-19 17:06:30 +00:00
committed by Gerrit Code Review
8 changed files with 276 additions and 56 deletions

View File

@@ -25559,6 +25559,7 @@ package android.net {
method public java.lang.String getName();
method public int getTruncationLengthBits();
method public void writeToParcel(android.os.Parcel, int);
field public static final java.lang.String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
@@ -25606,6 +25607,7 @@ package android.net {
public static class IpSecTransform.Builder {
ctor public IpSecTransform.Builder(android.content.Context);
method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
method public android.net.IpSecTransform.Builder setAuthenticatedEncryption(int, android.net.IpSecAlgorithm);
method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);

View File

@@ -27755,6 +27755,7 @@ package android.net {
method public java.lang.String getName();
method public int getTruncationLengthBits();
method public void writeToParcel(android.os.Parcel, int);
field public static final java.lang.String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
@@ -27802,6 +27803,7 @@ package android.net {
public static class IpSecTransform.Builder {
ctor public IpSecTransform.Builder(android.content.Context);
method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
method public android.net.IpSecTransform.Builder setAuthenticatedEncryption(int, android.net.IpSecAlgorithm);
method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);

View File

@@ -25668,6 +25668,7 @@ package android.net {
method public java.lang.String getName();
method public int getTruncationLengthBits();
method public void writeToParcel(android.os.Parcel, int);
field public static final java.lang.String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
@@ -25715,6 +25716,7 @@ package android.net {
public static class IpSecTransform.Builder {
ctor public IpSecTransform.Builder(android.content.Context);
method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
method public android.net.IpSecTransform.Builder setAuthenticatedEncryption(int, android.net.IpSecAlgorithm);
method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);

View File

@@ -31,7 +31,6 @@ import java.util.Arrays;
* RFC 4301.
*/
public final class IpSecAlgorithm implements Parcelable {
/**
* AES-CBC Encryption/Ciphering Algorithm.
*
@@ -68,6 +67,7 @@ public final class IpSecAlgorithm implements Parcelable {
* <p>Valid truncation lengths are multiples of 8 bits from 192 to (default) 384.
*/
public static final String AUTH_HMAC_SHA384 = "hmac(sha384)";
/**
* SHA512 HMAC Authentication/Integrity Algorithm
*
@@ -75,8 +75,24 @@ public final class IpSecAlgorithm implements Parcelable {
*/
public static final String AUTH_HMAC_SHA512 = "hmac(sha512)";
/**
* AES-GCM Authentication/Integrity + Encryption/Ciphering Algorithm.
*
* <p>Valid lengths for this key are {128, 192, 256}.
*
* <p>Valid ICV (truncation) lengths are {64, 96, 128}.
*/
public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
/** @hide */
@StringDef({CRYPT_AES_CBC, AUTH_HMAC_MD5, AUTH_HMAC_SHA1, AUTH_HMAC_SHA256, AUTH_HMAC_SHA512})
@StringDef({
CRYPT_AES_CBC,
AUTH_HMAC_MD5,
AUTH_HMAC_SHA1,
AUTH_HMAC_SHA256,
AUTH_HMAC_SHA512,
AUTH_CRYPT_AES_GCM
})
@Retention(RetentionPolicy.SOURCE)
public @interface AlgorithmName {}
@@ -102,7 +118,7 @@ public final class IpSecAlgorithm implements Parcelable {
* @param algoName precise name of the algorithm to be used.
* @param key non-null Key padded to a multiple of 8 bits.
* @param truncLenBits the number of bits of output hash to use; only meaningful for
* Authentication.
* Authentication or Authenticated Encryption (equivalent to ICV length).
*/
public IpSecAlgorithm(@AlgorithmName String algoName, byte[] key, int truncLenBits) {
if (!isTruncationLengthValid(algoName, truncLenBits)) {
@@ -175,6 +191,8 @@ public final class IpSecAlgorithm implements Parcelable {
return (truncLenBits >= 192 && truncLenBits <= 384);
case AUTH_HMAC_SHA512:
return (truncLenBits >= 256 && truncLenBits <= 512);
case AUTH_CRYPT_AES_GCM:
return (truncLenBits == 64 || truncLenBits == 96 || truncLenBits == 128);
default:
return false;
}

View File

@@ -50,6 +50,9 @@ public final class IpSecConfig implements Parcelable {
// Authentication Algorithm
private IpSecAlgorithm mAuthentication;
// Authenticated Encryption Algorithm
private IpSecAlgorithm mAuthenticatedEncryption;
@Override
public String toString() {
return new StringBuilder()
@@ -59,6 +62,8 @@ public final class IpSecConfig implements Parcelable {
.append(mEncryption)
.append(", mAuthentication=")
.append(mAuthentication)
.append(", mAuthenticatedEncryption=")
.append(mAuthenticatedEncryption)
.append("}")
.toString();
}
@@ -118,6 +123,11 @@ public final class IpSecConfig implements Parcelable {
mFlow[direction].mAuthentication = authentication;
}
/** Set the authenticated encryption algorithm for a given direction */
public void setAuthenticatedEncryption(int direction, IpSecAlgorithm authenticatedEncryption) {
mFlow[direction].mAuthenticatedEncryption = authenticatedEncryption;
}
public void setNetwork(Network network) {
mNetwork = network;
}
@@ -163,6 +173,10 @@ public final class IpSecConfig implements Parcelable {
return mFlow[direction].mAuthentication;
}
public IpSecAlgorithm getAuthenticatedEncryption(int direction) {
return mFlow[direction].mAuthenticatedEncryption;
}
public Network getNetwork() {
return mNetwork;
}
@@ -199,9 +213,11 @@ public final class IpSecConfig implements Parcelable {
out.writeInt(mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mEncryption, flags);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthentication, flags);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthenticatedEncryption, flags);
out.writeInt(mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mEncryption, flags);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication, flags);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption, flags);
out.writeInt(mEncapType);
out.writeInt(mEncapSocketResourceId);
out.writeInt(mEncapRemotePort);
@@ -221,11 +237,15 @@ public final class IpSecConfig implements Parcelable {
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mFlow[IpSecTransform.DIRECTION_IN].mAuthentication =
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mFlow[IpSecTransform.DIRECTION_IN].mAuthenticatedEncryption =
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId = in.readInt();
mFlow[IpSecTransform.DIRECTION_OUT].mEncryption =
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication =
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption =
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mEncapType = in.readInt();
mEncapSocketResourceId = in.readInt();
mEncapRemotePort = in.readInt();

View File

@@ -281,6 +281,8 @@ public final class IpSecTransform implements AutoCloseable {
* <p>If encryption is set for a given direction without also providing an SPI for that
* direction, creation of an IpSecTransform will fail upon calling a build() method.
*
* <p>Authenticated encryption is mutually exclusive with encryption and authentication.
*
* @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
* @param algo {@link IpSecAlgorithm} specifying the encryption to be applied.
*/
@@ -296,6 +298,8 @@ public final class IpSecTransform implements AutoCloseable {
* <p>If authentication is set for a given direction without also providing an SPI for that
* direction, creation of an IpSecTransform will fail upon calling a build() method.
*
* <p>Authenticated encryption is mutually exclusive with encryption and authentication.
*
* @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
* @param algo {@link IpSecAlgorithm} specifying the authentication to be applied.
*/
@@ -305,6 +309,29 @@ public final class IpSecTransform implements AutoCloseable {
return this;
}
/**
* Add an authenticated encryption algorithm to the transform for the given direction.
*
* <p>If an authenticated encryption algorithm is set for a given direction without also
* providing an SPI for that direction, creation of an IpSecTransform will fail upon calling
* a build() method.
*
* <p>The Authenticated Encryption (AE) class of algorithms are also known as Authenticated
* Encryption with Associated Data (AEAD) algorithms, or Combined mode algorithms (as
* referred to in RFC 4301)
*
* <p>Authenticated encryption is mutually exclusive with encryption and authentication.
*
* @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
* @param algo {@link IpSecAlgorithm} specifying the authenticated encryption algorithm to
* be applied.
*/
public IpSecTransform.Builder setAuthenticatedEncryption(
@TransformDirection int direction, IpSecAlgorithm algo) {
mConfig.setAuthenticatedEncryption(direction, algo);
return this;
}
/**
* Set the SPI, which uniquely identifies a particular IPsec session from others. Because
* IPsec operates at the IP layer, this 32-bit identifier uniquely identifies packets to a

View File

@@ -882,8 +882,14 @@ public class IpSecService extends IIpSecService.Stub {
for (int direction : DIRECTIONS) {
IpSecAlgorithm crypt = config.getEncryption(direction);
IpSecAlgorithm auth = config.getAuthentication(direction);
if (crypt == null && auth == null) {
throw new IllegalArgumentException("Encryption and Authentication are both null");
IpSecAlgorithm authenticatedEncryption = config.getAuthenticatedEncryption(direction);
if (authenticatedEncryption == null && crypt == null && auth == null) {
throw new IllegalArgumentException(
"No Encryption or Authentication algorithms specified");
} else if (authenticatedEncryption != null && (auth != null || crypt != null)) {
throw new IllegalArgumentException(
"Authenticated Encryption is mutually"
+ " exclusive with other Authentication or Encryption algorithms");
}
if (mSpiRecords.getAndCheckOwner(config.getSpiResourceId(direction)) == null) {
@@ -922,6 +928,7 @@ public class IpSecService extends IIpSecService.Stub {
for (int direction : DIRECTIONS) {
IpSecAlgorithm auth = c.getAuthentication(direction);
IpSecAlgorithm crypt = c.getEncryption(direction);
IpSecAlgorithm authCrypt = c.getAuthenticatedEncryption(direction);
spis[direction] = mSpiRecords.getAndCheckOwner(c.getSpiResourceId(direction));
int spi = spis[direction].getSpi();
@@ -942,6 +949,9 @@ public class IpSecService extends IIpSecService.Stub {
(crypt != null) ? crypt.getName() : "",
(crypt != null) ? crypt.getKey() : null,
(crypt != null) ? crypt.getTruncationLengthBits() : 0,
(authCrypt != null) ? authCrypt.getName() : "",
(authCrypt != null) ? authCrypt.getKey() : null,
(authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0,
encapType,
encapLocalPort,
encapRemotePort);

View File

@@ -17,10 +17,12 @@
package com.android.server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -37,7 +39,6 @@ import android.net.NetworkUtils;
import android.os.Binder;
import android.os.ParcelFileDescriptor;
import android.support.test.filters.SmallTest;
import android.system.OsConstants;
import java.net.Socket;
import java.util.Arrays;
@@ -53,8 +54,8 @@ import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class IpSecServiceParameterizedTest {
private static final int DROID_SPI = 0xD1201D;
private static final int DROID_SPI2 = DROID_SPI + 1;
private static final int TEST_SPI_OUT = 0xD1201D;
private static final int TEST_SPI_IN = TEST_SPI_OUT + 1;
private final String mRemoteAddr;
@@ -81,6 +82,16 @@ public class IpSecServiceParameterizedTest {
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
private static final IpSecAlgorithm AUTH_ALGO =
new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4);
private static final IpSecAlgorithm CRYPT_ALGO =
new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
private static final IpSecAlgorithm AEAD_ALGO =
new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, CRYPT_KEY, CRYPT_KEY.length * 4);
private static final int[] DIRECTIONS =
new int[] {IpSecTransform.DIRECTION_IN, IpSecTransform.DIRECTION_OUT};
public IpSecServiceParameterizedTest(String remoteAddr) {
mRemoteAddr = remoteAddr;
}
@@ -103,14 +114,14 @@ public class IpSecServiceParameterizedTest {
eq(IpSecTransform.DIRECTION_OUT),
anyString(),
eq(mRemoteAddr),
eq(DROID_SPI)))
.thenReturn(DROID_SPI);
eq(TEST_SPI_OUT)))
.thenReturn(TEST_SPI_OUT);
IpSecSpiResponse spiResp =
mIpSecService.reserveSecurityParameterIndex(
IpSecTransform.DIRECTION_OUT, mRemoteAddr, DROID_SPI, new Binder());
IpSecTransform.DIRECTION_OUT, mRemoteAddr, TEST_SPI_OUT, new Binder());
assertEquals(IpSecManager.Status.OK, spiResp.status);
assertEquals(DROID_SPI, spiResp.spi);
assertEquals(TEST_SPI_OUT, spiResp.spi);
}
@Test
@@ -120,56 +131,60 @@ public class IpSecServiceParameterizedTest {
eq(IpSecTransform.DIRECTION_OUT),
anyString(),
eq(mRemoteAddr),
eq(DROID_SPI)))
.thenReturn(DROID_SPI);
eq(TEST_SPI_OUT)))
.thenReturn(TEST_SPI_OUT);
IpSecSpiResponse spiResp =
mIpSecService.reserveSecurityParameterIndex(
IpSecTransform.DIRECTION_OUT, mRemoteAddr, DROID_SPI, new Binder());
IpSecTransform.DIRECTION_OUT, mRemoteAddr, TEST_SPI_OUT, new Binder());
mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
verify(mMockNetd)
.ipSecDeleteSecurityAssociation(
eq(spiResp.resourceId), anyInt(), anyString(), anyString(), eq(DROID_SPI));
eq(spiResp.resourceId),
anyInt(),
anyString(),
anyString(),
eq(TEST_SPI_OUT));
}
IpSecConfig buildIpSecConfig() throws Exception {
IpSecManager ipSecManager = new IpSecManager(mIpSecService);
// Mocking the netd to allocate SPI
private int getNewSpiResourceId(int direction, String remoteAddress, int returnSpi)
throws Exception {
when(mMockNetd.ipSecAllocateSpi(anyInt(), anyInt(), anyString(), anyString(), anyInt()))
.thenReturn(DROID_SPI)
.thenReturn(DROID_SPI2);
.thenReturn(returnSpi);
IpSecAlgorithm encryptAlgo = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
IpSecAlgorithm authAlgo =
new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 8);
IpSecSpiResponse spi =
mIpSecService.reserveSecurityParameterIndex(
direction,
NetworkUtils.numericToInetAddress(remoteAddress).getHostAddress(),
IpSecManager.INVALID_SECURITY_PARAMETER_INDEX,
new Binder());
return spi.resourceId;
}
/** Allocate and add SPI records in the IpSecService through IpSecManager interface. */
IpSecManager.SecurityParameterIndex outSpi =
ipSecManager.reserveSecurityParameterIndex(
IpSecTransform.DIRECTION_OUT,
NetworkUtils.numericToInetAddress(mRemoteAddr));
IpSecManager.SecurityParameterIndex inSpi =
ipSecManager.reserveSecurityParameterIndex(
IpSecTransform.DIRECTION_IN,
NetworkUtils.numericToInetAddress(mRemoteAddr));
IpSecConfig config = new IpSecConfig();
config.setSpiResourceId(IpSecTransform.DIRECTION_IN, inSpi.getResourceId());
config.setSpiResourceId(IpSecTransform.DIRECTION_OUT, outSpi.getResourceId());
config.setEncryption(IpSecTransform.DIRECTION_OUT, encryptAlgo);
config.setAuthentication(IpSecTransform.DIRECTION_OUT, authAlgo);
config.setEncryption(IpSecTransform.DIRECTION_IN, encryptAlgo);
config.setAuthentication(IpSecTransform.DIRECTION_IN, authAlgo);
private void addDefaultSpisAndRemoteAddrToIpSecConfig(IpSecConfig config) throws Exception {
config.setSpiResourceId(
IpSecTransform.DIRECTION_OUT,
getNewSpiResourceId(IpSecTransform.DIRECTION_OUT, mRemoteAddr, TEST_SPI_OUT));
config.setSpiResourceId(
IpSecTransform.DIRECTION_IN,
getNewSpiResourceId(IpSecTransform.DIRECTION_IN, mRemoteAddr, TEST_SPI_IN));
config.setRemoteAddress(mRemoteAddr);
return config;
}
private void addAuthAndCryptToIpSecConfig(IpSecConfig config) throws Exception {
for (int direction : DIRECTIONS) {
config.setEncryption(direction, CRYPT_ALGO);
config.setAuthentication(direction, AUTH_ALGO);
}
}
@Test
public void testCreateTransportModeTransform() throws Exception {
IpSecConfig ipSecConfig = buildIpSecConfig();
IpSecConfig ipSecConfig = new IpSecConfig();
addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
@@ -183,13 +198,72 @@ public class IpSecServiceParameterizedTest {
anyString(),
anyString(),
anyLong(),
eq(DROID_SPI),
eq(TEST_SPI_OUT),
eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
eq(AUTH_KEY),
anyInt(),
eq(IpSecAlgorithm.CRYPT_AES_CBC),
eq(CRYPT_KEY),
anyInt(),
eq(""),
isNull(),
eq(0),
anyInt(),
anyInt(),
anyInt());
verify(mMockNetd)
.ipSecAddSecurityAssociation(
eq(createTransformResp.resourceId),
anyInt(),
eq(IpSecTransform.DIRECTION_IN),
anyString(),
anyString(),
anyLong(),
eq(TEST_SPI_IN),
eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
eq(AUTH_KEY),
anyInt(),
eq(IpSecAlgorithm.CRYPT_AES_CBC),
eq(CRYPT_KEY),
anyInt(),
eq(""),
isNull(),
eq(0),
anyInt(),
anyInt(),
anyInt());
}
@Test
public void testCreateTransportModeTransformAead() throws Exception {
IpSecConfig ipSecConfig = new IpSecConfig();
addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
ipSecConfig.setAuthenticatedEncryption(IpSecTransform.DIRECTION_OUT, AEAD_ALGO);
ipSecConfig.setAuthenticatedEncryption(IpSecTransform.DIRECTION_IN, AEAD_ALGO);
IpSecTransformResponse createTransformResp =
mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
assertEquals(IpSecManager.Status.OK, createTransformResp.status);
verify(mMockNetd)
.ipSecAddSecurityAssociation(
eq(createTransformResp.resourceId),
anyInt(),
eq(IpSecTransform.DIRECTION_OUT),
anyString(),
anyString(),
anyLong(),
eq(TEST_SPI_OUT),
eq(""),
isNull(),
eq(0),
eq(""),
isNull(),
eq(0),
eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM),
eq(CRYPT_KEY),
anyInt(),
anyInt(),
anyInt(),
anyInt());
@@ -201,11 +275,14 @@ public class IpSecServiceParameterizedTest {
anyString(),
anyString(),
anyLong(),
eq(DROID_SPI2),
eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
eq(AUTH_KEY),
anyInt(),
eq(IpSecAlgorithm.CRYPT_AES_CBC),
eq(TEST_SPI_IN),
eq(""),
isNull(),
eq(0),
eq(""),
isNull(),
eq(0),
eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM),
eq(CRYPT_KEY),
anyInt(),
anyInt(),
@@ -213,9 +290,69 @@ public class IpSecServiceParameterizedTest {
anyInt());
}
@Test
public void testCreateInvalidConfigAeadWithAuth() throws Exception {
IpSecConfig ipSecConfig = new IpSecConfig();
addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
for (int direction : DIRECTIONS) {
ipSecConfig.setAuthentication(direction, AUTH_ALGO);
ipSecConfig.setAuthenticatedEncryption(direction, AEAD_ALGO);
}
try {
mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
fail(
"IpSecService should have thrown an error on authentication being"
+ " enabled with authenticated encryption");
} catch (IllegalArgumentException expected) {
}
}
@Test
public void testCreateInvalidConfigAeadWithCrypt() throws Exception {
IpSecConfig ipSecConfig = new IpSecConfig();
addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
for (int direction : DIRECTIONS) {
ipSecConfig.setEncryption(direction, CRYPT_ALGO);
ipSecConfig.setAuthenticatedEncryption(direction, AEAD_ALGO);
}
try {
mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
fail(
"IpSecService should have thrown an error on encryption being"
+ " enabled with authenticated encryption");
} catch (IllegalArgumentException expected) {
}
}
@Test
public void testCreateInvalidConfigAeadWithAuthAndCrypt() throws Exception {
IpSecConfig ipSecConfig = new IpSecConfig();
addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
for (int direction : DIRECTIONS) {
ipSecConfig.setAuthentication(direction, AUTH_ALGO);
ipSecConfig.setEncryption(direction, CRYPT_ALGO);
ipSecConfig.setAuthenticatedEncryption(direction, AEAD_ALGO);
}
try {
mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
fail(
"IpSecService should have thrown an error on authentication and encryption being"
+ " enabled with authenticated encryption");
} catch (IllegalArgumentException expected) {
}
}
@Test
public void testDeleteTransportModeTransform() throws Exception {
IpSecConfig ipSecConfig = buildIpSecConfig();
IpSecConfig ipSecConfig = new IpSecConfig();
addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
@@ -227,19 +364,21 @@ public class IpSecServiceParameterizedTest {
eq(IpSecTransform.DIRECTION_OUT),
anyString(),
anyString(),
eq(DROID_SPI));
eq(TEST_SPI_OUT));
verify(mMockNetd)
.ipSecDeleteSecurityAssociation(
eq(createTransformResp.resourceId),
eq(IpSecTransform.DIRECTION_IN),
anyString(),
anyString(),
eq(DROID_SPI2));
eq(TEST_SPI_IN));
}
@Test
public void testApplyTransportModeTransform() throws Exception {
IpSecConfig ipSecConfig = buildIpSecConfig();
IpSecConfig ipSecConfig = new IpSecConfig();
addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
mIpSecService.createTransportModeTransform(ipSecConfig, new Binder());
@@ -255,7 +394,7 @@ public class IpSecServiceParameterizedTest {
eq(IpSecTransform.DIRECTION_OUT),
anyString(),
anyString(),
eq(DROID_SPI));
eq(TEST_SPI_OUT));
verify(mMockNetd)
.ipSecApplyTransportModeTransform(
eq(pfd.getFileDescriptor()),
@@ -263,7 +402,7 @@ public class IpSecServiceParameterizedTest {
eq(IpSecTransform.DIRECTION_IN),
anyString(),
anyString(),
eq(DROID_SPI2));
eq(TEST_SPI_IN));
}
@Test