Merge "Add support for AES-GCM-ESP as an IPSec algorithm" am: b6df7f0d35 am: cb2c14fc55

am: f92bfc3b77

Change-Id: I49932a5fc048b4a60512fac45a3537f050397168
This commit is contained in:
Benedict Wong
2017-10-19 17:37:22 +00:00
committed by android-build-merger
4 changed files with 80 additions and 5 deletions

View File

@@ -31,7 +31,6 @@ import java.util.Arrays;
* RFC 4301. * RFC 4301.
*/ */
public final class IpSecAlgorithm implements Parcelable { public final class IpSecAlgorithm implements Parcelable {
/** /**
* AES-CBC Encryption/Ciphering Algorithm. * 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. * <p>Valid truncation lengths are multiples of 8 bits from 192 to (default) 384.
*/ */
public static final String AUTH_HMAC_SHA384 = "hmac(sha384)"; public static final String AUTH_HMAC_SHA384 = "hmac(sha384)";
/** /**
* SHA512 HMAC Authentication/Integrity Algorithm * SHA512 HMAC Authentication/Integrity Algorithm
* *
@@ -75,8 +75,24 @@ public final class IpSecAlgorithm implements Parcelable {
*/ */
public static final String AUTH_HMAC_SHA512 = "hmac(sha512)"; 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 */ /** @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) @Retention(RetentionPolicy.SOURCE)
public @interface AlgorithmName {} public @interface AlgorithmName {}
@@ -102,7 +118,7 @@ public final class IpSecAlgorithm implements Parcelable {
* @param algoName precise name of the algorithm to be used. * @param algoName precise name of the algorithm to be used.
* @param key non-null Key padded to a multiple of 8 bits. * @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 * @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) { public IpSecAlgorithm(@AlgorithmName String algoName, byte[] key, int truncLenBits) {
if (!isTruncationLengthValid(algoName, truncLenBits)) { if (!isTruncationLengthValid(algoName, truncLenBits)) {
@@ -175,6 +191,8 @@ public final class IpSecAlgorithm implements Parcelable {
return (truncLenBits >= 192 && truncLenBits <= 384); return (truncLenBits >= 192 && truncLenBits <= 384);
case AUTH_HMAC_SHA512: case AUTH_HMAC_SHA512:
return (truncLenBits >= 256 && truncLenBits <= 512); return (truncLenBits >= 256 && truncLenBits <= 512);
case AUTH_CRYPT_AES_GCM:
return (truncLenBits == 64 || truncLenBits == 96 || truncLenBits == 128);
default: default:
return false; return false;
} }

View File

@@ -50,6 +50,9 @@ public final class IpSecConfig implements Parcelable {
// Authentication Algorithm // Authentication Algorithm
private IpSecAlgorithm mAuthentication; private IpSecAlgorithm mAuthentication;
// Authenticated Encryption Algorithm
private IpSecAlgorithm mAuthenticatedEncryption;
@Override @Override
public String toString() { public String toString() {
return new StringBuilder() return new StringBuilder()
@@ -59,6 +62,8 @@ public final class IpSecConfig implements Parcelable {
.append(mEncryption) .append(mEncryption)
.append(", mAuthentication=") .append(", mAuthentication=")
.append(mAuthentication) .append(mAuthentication)
.append(", mAuthenticatedEncryption=")
.append(mAuthenticatedEncryption)
.append("}") .append("}")
.toString(); .toString();
} }
@@ -118,6 +123,11 @@ public final class IpSecConfig implements Parcelable {
mFlow[direction].mAuthentication = authentication; 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) { public void setNetwork(Network network) {
mNetwork = network; mNetwork = network;
} }
@@ -163,6 +173,10 @@ public final class IpSecConfig implements Parcelable {
return mFlow[direction].mAuthentication; return mFlow[direction].mAuthentication;
} }
public IpSecAlgorithm getAuthenticatedEncryption(int direction) {
return mFlow[direction].mAuthenticatedEncryption;
}
public Network getNetwork() { public Network getNetwork() {
return mNetwork; return mNetwork;
} }
@@ -199,9 +213,11 @@ public final class IpSecConfig implements Parcelable {
out.writeInt(mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId); out.writeInt(mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mEncryption, flags); out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mEncryption, flags);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthentication, 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.writeInt(mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mEncryption, flags); out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mEncryption, flags);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication, flags); out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication, flags);
out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption, flags);
out.writeInt(mEncapType); out.writeInt(mEncapType);
out.writeInt(mEncapSocketResourceId); out.writeInt(mEncapSocketResourceId);
out.writeInt(mEncapRemotePort); out.writeInt(mEncapRemotePort);
@@ -221,11 +237,15 @@ public final class IpSecConfig implements Parcelable {
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mFlow[IpSecTransform.DIRECTION_IN].mAuthentication = mFlow[IpSecTransform.DIRECTION_IN].mAuthentication =
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); (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].mSpiResourceId = in.readInt();
mFlow[IpSecTransform.DIRECTION_OUT].mEncryption = mFlow[IpSecTransform.DIRECTION_OUT].mEncryption =
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication = mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication =
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption =
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
mEncapType = in.readInt(); mEncapType = in.readInt();
mEncapSocketResourceId = in.readInt(); mEncapSocketResourceId = in.readInt();
mEncapRemotePort = 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 * <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. * 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 direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
* @param algo {@link IpSecAlgorithm} specifying the encryption to be applied. * @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 * <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. * 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 direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
* @param algo {@link IpSecAlgorithm} specifying the authentication to be applied. * @param algo {@link IpSecAlgorithm} specifying the authentication to be applied.
*/ */
@@ -305,6 +309,29 @@ public final class IpSecTransform implements AutoCloseable {
return this; 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 * 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 * 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) { for (int direction : DIRECTIONS) {
IpSecAlgorithm crypt = config.getEncryption(direction); IpSecAlgorithm crypt = config.getEncryption(direction);
IpSecAlgorithm auth = config.getAuthentication(direction); IpSecAlgorithm auth = config.getAuthentication(direction);
if (crypt == null && auth == null) { IpSecAlgorithm authenticatedEncryption = config.getAuthenticatedEncryption(direction);
throw new IllegalArgumentException("Encryption and Authentication are both null"); 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) { if (mSpiRecords.getAndCheckOwner(config.getSpiResourceId(direction)) == null) {
@@ -922,6 +928,7 @@ public class IpSecService extends IIpSecService.Stub {
for (int direction : DIRECTIONS) { for (int direction : DIRECTIONS) {
IpSecAlgorithm auth = c.getAuthentication(direction); IpSecAlgorithm auth = c.getAuthentication(direction);
IpSecAlgorithm crypt = c.getEncryption(direction); IpSecAlgorithm crypt = c.getEncryption(direction);
IpSecAlgorithm authCrypt = c.getAuthenticatedEncryption(direction);
spis[direction] = mSpiRecords.getAndCheckOwner(c.getSpiResourceId(direction)); spis[direction] = mSpiRecords.getAndCheckOwner(c.getSpiResourceId(direction));
int spi = spis[direction].getSpi(); int spi = spis[direction].getSpi();
@@ -942,6 +949,9 @@ public class IpSecService extends IIpSecService.Stub {
(crypt != null) ? crypt.getName() : "", (crypt != null) ? crypt.getName() : "",
(crypt != null) ? crypt.getKey() : null, (crypt != null) ? crypt.getKey() : null,
(crypt != null) ? crypt.getTruncationLengthBits() : 0, (crypt != null) ? crypt.getTruncationLengthBits() : 0,
(authCrypt != null) ? authCrypt.getName() : "",
(authCrypt != null) ? authCrypt.getKey() : null,
(authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0,
encapType, encapType,
encapLocalPort, encapLocalPort,
encapRemotePort); encapRemotePort);