Merge "Add support for AES-GCM-ESP as an IPSec algorithm"
am: b6df7f0d35 Change-Id: Ic099206a28c4f21fa796969c953a8d4e81e8495b
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user