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

Commit bb7f2820 authored by Benedict Wong's avatar Benedict Wong
Browse files

Require explicitly supplied truncation length

Instead of providing default truncation lengths (based on RFC or
otherwise), this change imposes a restriction that the truncation length
must be supplied for all auth or aead algorithms.

Bug: 77204048
Test: Updated tests, ran on walleye
Change-Id: I4a0e2e71aa97259e56f44e7c8a2ce53135708d97
parent 8d8921d7
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -56,7 +56,8 @@ public final class IpSecAlgorithm implements Parcelable {
     * new applications and is provided for legacy compatibility with 3gpp infrastructure.</b>
     *
     * <p>Keys for this algorithm must be 128 bits in length.
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 128.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to 128.
     */
    public static final String AUTH_HMAC_MD5 = "hmac(md5)";

@@ -65,7 +66,8 @@ public final class IpSecAlgorithm implements Parcelable {
     * new applications and is provided for legacy compatibility with 3gpp infrastructure.</b>
     *
     * <p>Keys for this algorithm must be 160 bits in length.
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 160.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to 160.
     */
    public static final String AUTH_HMAC_SHA1 = "hmac(sha1)";

@@ -73,7 +75,8 @@ public final class IpSecAlgorithm implements Parcelable {
     * SHA256 HMAC Authentication/Integrity Algorithm.
     *
     * <p>Keys for this algorithm must be 256 bits in length.
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 256.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to 256.
     */
    public static final String AUTH_HMAC_SHA256 = "hmac(sha256)";

@@ -81,7 +84,8 @@ public final class IpSecAlgorithm implements Parcelable {
     * SHA384 HMAC Authentication/Integrity Algorithm.
     *
     * <p>Keys for this algorithm must be 384 bits in length.
     * <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 384.
     */
    public static final String AUTH_HMAC_SHA384 = "hmac(sha384)";

@@ -89,7 +93,8 @@ public final class IpSecAlgorithm implements Parcelable {
     * SHA512 HMAC Authentication/Integrity Algorithm.
     *
     * <p>Keys for this algorithm must be 512 bits in length.
     * <p>Valid truncation lengths are multiples of 8 bits from 256 to (default) 512.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 256 to 512.
     */
    public static final String AUTH_HMAC_SHA512 = "hmac(sha512)";

@@ -112,6 +117,7 @@ public final class IpSecAlgorithm implements Parcelable {
        AUTH_HMAC_MD5,
        AUTH_HMAC_SHA1,
        AUTH_HMAC_SHA256,
        AUTH_HMAC_SHA384,
        AUTH_HMAC_SHA512,
        AUTH_CRYPT_AES_GCM
    })
@@ -126,11 +132,14 @@ public final class IpSecAlgorithm implements Parcelable {
     * Creates an IpSecAlgorithm of one of the supported types. Supported algorithm names are
     * defined as constants in this class.
     *
     * <p>For algorithms that produce an integrity check value, the truncation length is a required
     * parameter. See {@link #IpSecAlgorithm(String algorithm, byte[] key, int truncLenBits)}
     *
     * @param algorithm name of the algorithm.
     * @param key key padded to a multiple of 8 bits.
     */
    public IpSecAlgorithm(@NonNull @AlgorithmName String algorithm, @NonNull byte[] key) {
        this(algorithm, key, key.length * 8);
        this(algorithm, key, 0);
    }

    /**
@@ -228,6 +237,7 @@ public final class IpSecAlgorithm implements Parcelable {
            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;
            default:
                throw new IllegalArgumentException("Couldn't find an algorithm: " + name);
+26 −12
Original line number Diff line number Diff line
@@ -22,8 +22,12 @@ import static org.junit.Assert.fail;
import android.os.Parcel;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.Map.Entry;
import java.util.Random;

import org.junit.Test;
import org.junit.runner.RunWith;

@@ -40,19 +44,29 @@ public class IpSecAlgorithmTest {
    };

    @Test
    public void testDefaultTruncLen() throws Exception {
        IpSecAlgorithm explicit =
                new IpSecAlgorithm(
                        IpSecAlgorithm.AUTH_HMAC_SHA256, Arrays.copyOf(KEY_MATERIAL, 256 / 8), 256);
        IpSecAlgorithm implicit =
    public void testNoTruncLen() throws Exception {
        Entry<String, Integer>[] authAndAeadList =
                new Entry[] {
                    new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_MD5, 128),
                    new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_SHA1, 160),
                    new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_SHA256, 256),
                    new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_SHA384, 384),
                    new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_SHA512, 512),
                    new SimpleEntry<>(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, 224)
                };

        // Expect auth and aead algorithms to throw errors if trunclen is omitted.
        for (Entry<String, Integer> algData : authAndAeadList) {
            try {
                new IpSecAlgorithm(
                        IpSecAlgorithm.AUTH_HMAC_SHA256, Arrays.copyOf(KEY_MATERIAL, 256 / 8));
        assertTrue(
                "Default Truncation Length Incorrect, Explicit: "
                        + explicit
                        + "implicit: "
                        + implicit,
                IpSecAlgorithm.equals(explicit, implicit));
                        algData.getKey(), Arrays.copyOf(KEY_MATERIAL, algData.getValue() / 8));
                fail("Expected exception on unprovided auth trunclen");
            } catch (IllegalArgumentException expected) {
            }
        }

        // Ensure crypt works with no truncation length supplied.
        new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, Arrays.copyOf(KEY_MATERIAL, 256 / 8));
    }

    @Test
+2 −1
Original line number Diff line number Diff line
@@ -62,7 +62,8 @@ public class IpSecConfigTest {
        c.setAuthentication(
                new IpSecAlgorithm(
                        IpSecAlgorithm.AUTH_HMAC_MD5,
                        new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0}));
                        new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0},
                        128));
        c.setAuthenticatedEncryption(
                new IpSecAlgorithm(
                        IpSecAlgorithm.AUTH_CRYPT_AES_GCM,