Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4cddef19 authored by Yan Yan's avatar Yan Yan Committed by Automerger Merge Worker
Browse files

Merge changes from topic "new-ipsec-api" am: a80fb3bb am: cb5aed65

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1398433

Change-Id: I45530694608909ddbb21d037cc3302130d8140c7
parents 93a785bd cb5aed65
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -30051,9 +30051,12 @@ package android.net {
    method public int describeContents();
    method @NonNull public byte[] getKey();
    method @NonNull public String getName();
    method @NonNull public static java.util.Set<java.lang.String> getSupportedAlgorithms();
    method public int getTruncationLengthBits();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final String AUTH_AES_XCBC = "xcbc(aes)";
    field public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
    field public static final String AUTH_CRYPT_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)";
    field public static final String AUTH_HMAC_MD5 = "hmac(md5)";
    field public static final String AUTH_HMAC_SHA1 = "hmac(sha1)";
    field public static final String AUTH_HMAC_SHA256 = "hmac(sha256)";
@@ -30061,6 +30064,7 @@ package android.net {
    field public static final String AUTH_HMAC_SHA512 = "hmac(sha512)";
    field @NonNull public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
    field public static final String CRYPT_AES_CBC = "cbc(aes)";
    field public static final String CRYPT_AES_CTR = "rfc3686(ctr(aes))";
  }
  public final class IpSecManager {
+172 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package android.net;

import android.annotation.NonNull;
import android.annotation.StringDef;
import android.content.res.Resources;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,6 +28,12 @@ import com.android.internal.util.HexDump;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * This class represents a single algorithm that can be used by an {@link IpSecTransform}.
@@ -51,6 +58,27 @@ public final class IpSecAlgorithm implements Parcelable {
     */
    public static final String CRYPT_AES_CBC = "cbc(aes)";

    /**
     * AES-CTR Encryption/Ciphering Algorithm.
     *
     * <p>Valid lengths for keying material are {160, 224, 288}.
     *
     * <p>As per <a href="https://tools.ietf.org/html/rfc3686#section-5.1">RFC3686 (Section
     * 5.1)</a>, keying material consists of a 128, 192, or 256 bit AES key followed by a 32-bit
     * nonce. RFC compliance requires that the nonce must be unique per security association.
     *
     * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
     * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
     * included in the returned algorithm set. The returned algorithm set will not change unless the
     * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
     * requested on an unsupported device.
     *
     * <p>@see {@link #getSupportedAlgorithms()}
     */
    // This algorithm may be available on devices released before Android 12, and is guaranteed
    // to be available on devices first shipped with Android 12 or later.
    public static final String CRYPT_AES_CTR = "rfc3686(ctr(aes))";

    /**
     * MD5 HMAC Authentication/Integrity Algorithm. <b>This algorithm is not recommended for use in
     * new applications and is provided for legacy compatibility with 3gpp infrastructure.</b>
@@ -98,6 +126,25 @@ public final class IpSecAlgorithm implements Parcelable {
     */
    public static final String AUTH_HMAC_SHA512 = "hmac(sha512)";

    /**
     * AES-XCBC Authentication/Integrity Algorithm.
     *
     * <p>Keys for this algorithm must be 128 bits in length.
     *
     * <p>The only valid truncation length is 96 bits.
     *
     * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
     * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
     * included in the returned algorithm set. The returned algorithm set will not change unless the
     * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
     * requested on an unsupported device.
     *
     * <p>@see {@link #getSupportedAlgorithms()}
     */
    // This algorithm may be available on devices released before Android 12, and is guaranteed
    // to be available on devices first shipped with Android 12 or later.
    public static final String AUTH_AES_XCBC = "xcbc(aes)";

    /**
     * AES-GCM Authentication/Integrity + Encryption/Ciphering Algorithm.
     *
@@ -111,19 +158,67 @@ public final class IpSecAlgorithm implements Parcelable {
     */
    public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";

    /**
     * ChaCha20-Poly1305 Authentication/Integrity + Encryption/Ciphering Algorithm.
     *
     * <p>Keys for this algorithm must be 288 bits in length.
     *
     * <p>As per <a href="https://tools.ietf.org/html/rfc7634#section-2">RFC7634 (Section 2)</a>,
     * keying material consists of a 256 bit key followed by a 32-bit salt. The salt is fixed per
     * security association.
     *
     * <p>The only valid ICV (truncation) length is 128 bits.
     *
     * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
     * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
     * included in the returned algorithm set. The returned algorithm set will not change unless the
     * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
     * requested on an unsupported device.
     *
     * <p>@see {@link #getSupportedAlgorithms()}
     */
    // This algorithm may be available on devices released before Android 12, and is guaranteed
    // to be available on devices first shipped with Android 12 or later.
    public static final String AUTH_CRYPT_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)";

    /** @hide */
    @StringDef({
        CRYPT_AES_CBC,
        CRYPT_AES_CTR,
        AUTH_HMAC_MD5,
        AUTH_HMAC_SHA1,
        AUTH_HMAC_SHA256,
        AUTH_HMAC_SHA384,
        AUTH_HMAC_SHA512,
        AUTH_CRYPT_AES_GCM
        AUTH_AES_XCBC,
        AUTH_CRYPT_AES_GCM,
        AUTH_CRYPT_CHACHA20_POLY1305
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface AlgorithmName {}

    /** @hide */
    @VisibleForTesting
    public static final Map<String, Integer> ALGO_TO_REQUIRED_FIRST_SDK = new HashMap<>();

    static {
        ALGO_TO_REQUIRED_FIRST_SDK.put(CRYPT_AES_CBC, Build.VERSION_CODES.P);
        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_MD5, Build.VERSION_CODES.P);
        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA1, Build.VERSION_CODES.P);
        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA256, Build.VERSION_CODES.P);
        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA384, Build.VERSION_CODES.P);
        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA512, Build.VERSION_CODES.P);
        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_CRYPT_AES_GCM, Build.VERSION_CODES.P);

        // STOPSHIP: b/170424293 Use Build.VERSION_CODES.S when it is defined
        ALGO_TO_REQUIRED_FIRST_SDK.put(CRYPT_AES_CTR, Build.VERSION_CODES.R + 1);
        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_XCBC, Build.VERSION_CODES.R + 1);
        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.R + 1);
    }

    private static final Set<String> ENABLED_ALGOS =
            Collections.unmodifiableSet(loadAlgos(Resources.getSystem()));

    private final String mName;
    private final byte[] mKey;
    private final int mTruncLenBits;
@@ -137,6 +232,7 @@ public final class IpSecAlgorithm implements Parcelable {
     *
     * @param algorithm name of the algorithm.
     * @param key key padded to a multiple of 8 bits.
     * @throws IllegalArgumentException if algorithm or key length is invalid.
     */
    public IpSecAlgorithm(@NonNull @AlgorithmName String algorithm, @NonNull byte[] key) {
        this(algorithm, key, 0);
@@ -152,6 +248,7 @@ public final class IpSecAlgorithm implements Parcelable {
     * @param algorithm name of the algorithm.
     * @param key key padded to a multiple of 8 bits.
     * @param truncLenBits number of bits of output hash to use.
     * @throws IllegalArgumentException if algorithm, key length or truncation length is invalid.
     */
    public IpSecAlgorithm(
            @NonNull @AlgorithmName String algorithm, @NonNull byte[] key, int truncLenBits) {
@@ -206,13 +303,59 @@ public final class IpSecAlgorithm implements Parcelable {
                }
            };

    /**
     * Returns supported IPsec algorithms for the current device.
     *
     * <p>Some algorithms may not be supported on old devices. Callers MUST check if an algorithm is
     * supported before using it.
     */
    @NonNull
    public static Set<String> getSupportedAlgorithms() {
        return ENABLED_ALGOS;
    }

    /** @hide */
    @VisibleForTesting
    public static Set<String> loadAlgos(Resources systemResources) {
        final Set<String> enabledAlgos = new HashSet<>();

        // Load and validate the optional algorithm resource. Undefined or duplicate algorithms in
        // the resource are not allowed.
        final String[] resourceAlgos = systemResources.getStringArray(
                com.android.internal.R.array.config_optionalIpSecAlgorithms);
        for (String str : resourceAlgos) {
            if (!ALGO_TO_REQUIRED_FIRST_SDK.containsKey(str) || !enabledAlgos.add(str)) {
                // This error should be caught by CTS and never be thrown to API callers
                throw new IllegalArgumentException("Invalid or repeated algorithm " + str);
            }
        }

        for (Entry<String, Integer> entry : ALGO_TO_REQUIRED_FIRST_SDK.entrySet()) {
            if (Build.VERSION.FIRST_SDK_INT >= entry.getValue()) {
                enabledAlgos.add(entry.getKey());
            }
        }

        return enabledAlgos;
    }

    private static void checkValidOrThrow(String name, int keyLen, int truncLen) {
        boolean isValidLen = true;
        boolean isValidTruncLen = true;
        final boolean isValidLen;
        final boolean isValidTruncLen;

        if (!getSupportedAlgorithms().contains(name)) {
            throw new IllegalArgumentException("Unsupported algorithm: " + name);
        }

        switch (name) {
            case CRYPT_AES_CBC:
                isValidLen = keyLen == 128 || keyLen == 192 || keyLen == 256;
                isValidTruncLen = true;
                break;
            case CRYPT_AES_CTR:
                // The keying material for AES-CTR is a key plus a 32-bit salt
                isValidLen = keyLen == 128 + 32 || keyLen == 192 + 32 || keyLen == 256 + 32;
                isValidTruncLen = true;
                break;
            case AUTH_HMAC_MD5:
                isValidLen = keyLen == 128;
@@ -234,12 +377,22 @@ public final class IpSecAlgorithm implements Parcelable {
                isValidLen = keyLen == 512;
                isValidTruncLen = truncLen >= 256 && truncLen <= 512;
                break;
            case AUTH_AES_XCBC:
                isValidLen = keyLen == 128;
                isValidTruncLen = truncLen == 96;
                break;
            case AUTH_CRYPT_AES_GCM:
                // The keying material for GCM is a key plus a 32-bit salt
                isValidLen = keyLen == 128 + 32 || keyLen == 192 + 32 || keyLen == 256 + 32;
                isValidTruncLen = truncLen == 64 || truncLen == 96 || truncLen == 128;
                break;
            case AUTH_CRYPT_CHACHA20_POLY1305:
                // The keying material for ChaCha20Poly1305 is a key plus a 32-bit salt
                isValidLen = keyLen == 256 + 32;
                isValidTruncLen = truncLen == 128;
                break;
            default:
                // Should never hit here.
                throw new IllegalArgumentException("Couldn't find an algorithm: " + name);
        }

@@ -260,6 +413,7 @@ public final class IpSecAlgorithm implements Parcelable {
            case AUTH_HMAC_SHA256:
            case AUTH_HMAC_SHA384:
            case AUTH_HMAC_SHA512:
            case AUTH_AES_XCBC:
                return true;
            default:
                return false;
@@ -268,12 +422,24 @@ public final class IpSecAlgorithm implements Parcelable {

    /** @hide */
    public boolean isEncryption() {
        return getName().equals(CRYPT_AES_CBC);
        switch (getName()) {
            case CRYPT_AES_CBC: // fallthrough
            case CRYPT_AES_CTR:
                return true;
            default:
                return false;
        }
    }

    /** @hide */
    public boolean isAead() {
        return getName().equals(AUTH_CRYPT_AES_GCM);
        switch (getName()) {
            case AUTH_CRYPT_AES_GCM: // fallthrough
            case AUTH_CRYPT_CHACHA20_POLY1305:
                return true;
            default:
                return false;
        }
    }

    // Because encryption keys are sensitive and userdebug builds are used by large user pools
+15 −0
Original line number Diff line number Diff line
@@ -1663,6 +1663,21 @@
        -->
    </string-array>

    <!-- Optional IPsec algorithms enabled by this device, defaulting to empty. OEMs can override
         it by providing a list of algorithm names in an overlay config.xml file.

         As Android releases new versions, more algorithms are becoming mandatory. Mandatory
         algorithms will be automatically enabled on the device. Optional algorithms need
         to be explicitly declared in this resource to be enabled.
             * SDK level 28 makes the following algorithms mandatory : "cbc(aes)", "hmac(md5)",
               "hmac(sha1)", "hmac(sha256)", "hmac(sha384)", "hmac(sha512)", "rfc4106(gcm(aes))"
             * SDK level 30 makes the following algorithms mandatory : "rfc3686(ctr(aes))",
               "xcbc(aes)", "rfc7539esp(chacha20,poly1305)"
     -->
    <string-array name="config_optionalIpSecAlgorithms" translatable="false">
        <!-- Add algorithm here -->
    </string-array>

    <!-- Boolean indicating if current platform supports bluetooth SCO for off call
    use cases -->
    <bool name="config_bluetooth_sco_off_call">true</bool>
+3 −0
Original line number Diff line number Diff line
@@ -3186,6 +3186,9 @@
  <!-- Network Recommendation -->
  <java-symbol type="string" name="config_defaultNetworkRecommendationProviderPackage" />

  <!-- Optional IPsec algorithms -->
  <java-symbol type="array" name="config_optionalIpSecAlgorithms" />

  <!-- Whether allow 3rd party apps on internal storage. -->
  <java-symbol type="bool" name="config_allow3rdPartyAppOnInternal" />

+4 −0
Original line number Diff line number Diff line
@@ -29830,9 +29830,12 @@ package android.net {
    method public int describeContents();
    method @NonNull public byte[] getKey();
    method @NonNull public String getName();
    method @NonNull public static java.util.Set<java.lang.String> getSupportedAlgorithms();
    method public int getTruncationLengthBits();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final String AUTH_AES_XCBC = "xcbc(aes)";
    field public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
    field public static final String AUTH_CRYPT_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)";
    field public static final String AUTH_HMAC_MD5 = "hmac(md5)";
    field public static final String AUTH_HMAC_SHA1 = "hmac(sha1)";
    field public static final String AUTH_HMAC_SHA256 = "hmac(sha256)";
@@ -29840,6 +29843,7 @@ package android.net {
    field public static final String AUTH_HMAC_SHA512 = "hmac(sha512)";
    field @NonNull public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
    field public static final String CRYPT_AES_CBC = "cbc(aes)";
    field public static final String CRYPT_AES_CTR = "rfc3686(ctr(aes))";
  }
  public final class IpSecManager {
Loading