Verify kernel implementation of AES-CTR

This CL adds a test to verify kernel implementation of AES-CTR

Since there is no hardware that first launched with SDK beyond R
at the time of writing this CL, new tests for AES-CTR were manually
enabled and verified on coral (coral-kernel already supports
AES-CTR)

Bug: 171083832
Test: atest IpSecAlgorithmImplTest
Change-Id: Ib626a6c3999b7d682d0858e92d0dbb5138fdc45d
This commit is contained in:
Yan Yan
2020-08-11 17:34:46 -07:00
parent 80be81b302
commit 0c60279648
3 changed files with 81 additions and 6 deletions

View File

@@ -17,6 +17,14 @@
package android.net.cts;
import static android.net.IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305;
import static android.net.IpSecAlgorithm.CRYPT_AES_CTR;
import static android.net.cts.PacketUtils.AES_CTR;
import static android.net.cts.PacketUtils.AES_CTR_BLK_SIZE;
import static android.net.cts.PacketUtils.AES_CTR_IV_LEN;
import static android.net.cts.PacketUtils.AES_CTR_KEY_LEN_20;
import static android.net.cts.PacketUtils.AES_CTR_KEY_LEN_28;
import static android.net.cts.PacketUtils.AES_CTR_KEY_LEN_36;
import static android.net.cts.PacketUtils.AES_CTR_SALT_LEN;
import static android.net.cts.PacketUtils.CHACHA20_POLY1305;
import static android.net.cts.PacketUtils.CHACHA20_POLY1305_BLK_SIZE;
import static android.net.cts.PacketUtils.CHACHA20_POLY1305_ICV_LEN;
@@ -43,6 +51,7 @@ import android.net.cts.PacketUtils.EspAeadCipher;
import android.net.cts.PacketUtils.EspAuth;
import android.net.cts.PacketUtils.EspAuthNull;
import android.net.cts.PacketUtils.EspCipher;
import android.net.cts.PacketUtils.EspCryptCipher;
import android.net.cts.PacketUtils.EspHeader;
import android.net.cts.PacketUtils.IpHeader;
import android.net.cts.PacketUtils.UdpHeader;
@@ -194,6 +203,41 @@ public class IpSecAlgorithmImplTest extends IpSecBaseTest {
}
}
private void checkAesCtr(int keyLen) throws Exception {
final byte[] cryptKey = getKeyBytes(keyLen);
final IpSecAlgorithm ipsecEncryptAlgo =
new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CTR, cryptKey);
final EspCipher espCipher =
new EspCryptCipher(
AES_CTR, AES_CTR_BLK_SIZE, cryptKey, AES_CTR_IV_LEN, AES_CTR_SALT_LEN);
runWithShellPermissionIdentity(new TestNetworkRunnable(new CheckCryptoImplTest(
ipsecEncryptAlgo, null /* ipsecAuthAlgo */, null /* ipsecAeadAlgo */,
espCipher, EspAuthNull.getInstance())));
}
@Test
public void testAesCtr160() throws Exception {
assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR));
checkAesCtr(AES_CTR_KEY_LEN_20);
}
@Test
public void testAesCtr224() throws Exception {
assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR));
checkAesCtr(AES_CTR_KEY_LEN_28);
}
@Test
public void testAesCtr288() throws Exception {
assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR));
checkAesCtr(AES_CTR_KEY_LEN_36);
}
@Test
public void testChaCha20Poly1305() throws Exception {
assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305));

View File

@@ -33,7 +33,7 @@ import static android.net.cts.PacketUtils.AES_CMAC_ICV_LEN;
import static android.net.cts.PacketUtils.AES_CMAC_KEY_LEN;
import static android.net.cts.PacketUtils.AES_CTR_BLK_SIZE;
import static android.net.cts.PacketUtils.AES_CTR_IV_LEN;
import static android.net.cts.PacketUtils.AES_CTR_KEY_LEN;
import static android.net.cts.PacketUtils.AES_CTR_KEY_LEN_20;
import static android.net.cts.PacketUtils.AES_GCM_BLK_SIZE;
import static android.net.cts.PacketUtils.AES_GCM_IV_LEN;
import static android.net.cts.PacketUtils.AES_XCBC_ICV_LEN;
@@ -928,7 +928,7 @@ public class IpSecManagerTest extends IpSecBaseTest {
}
private static IpSecAlgorithm buildCryptAesCtr() throws Exception {
return new IpSecAlgorithm(CRYPT_AES_CTR, getKeyBytes(AES_CTR_KEY_LEN));
return new IpSecAlgorithm(CRYPT_AES_CTR, getKeyBytes(AES_CTR_KEY_LEN_20));
}
private static IpSecAlgorithm buildAuthHmacSha512() throws Exception {

View File

@@ -54,8 +54,11 @@ public class PacketUtils {
// Encryption parameters
static final int AES_CBC_IV_LEN = 16;
static final int AES_CBC_BLK_SIZE = 16;
static final int AES_CTR_SALT_LEN = 4;
static final int AES_CTR_KEY_LEN = 20;
static final int AES_CTR_KEY_LEN_20 = 20;
static final int AES_CTR_KEY_LEN_28 = 28;
static final int AES_CTR_KEY_LEN_36 = 36;
static final int AES_CTR_BLK_SIZE = ESP_BLK_SIZE;
static final int AES_CTR_IV_LEN = 8;
@@ -77,9 +80,13 @@ public class PacketUtils {
static final int AES_CMAC_KEY_LEN = 16;
static final int AES_CMAC_ICV_LEN = 12;
// Block counter field should be 32 bits and starts from value one as per RFC 3686
static final byte[] AES_CTR_INITIAL_COUNTER = new byte[] {0x00, 0x00, 0x00, 0x01};
// Encryption algorithms
static final String AES = "AES";
static final String AES_CBC = "AES/CBC/NoPadding";
static final String AES_CTR = "AES/CTR/NoPadding";
// AEAD algorithms
static final String CHACHA20_POLY1305 = "ChaCha20/Poly1305/NoPadding";
@@ -552,14 +559,38 @@ public class PacketUtils {
public static class EspCryptCipher extends EspCipher {
public EspCryptCipher(String algoName, int blockSize, byte[] key, int ivLen) {
super(algoName, blockSize, key, ivLen, SALT_LEN_UNUSED);
this(algoName, blockSize, key, ivLen, SALT_LEN_UNUSED);
}
public EspCryptCipher(String algoName, int blockSize, byte[] key, int ivLen, int saltLen) {
super(algoName, blockSize, key, ivLen, saltLen);
}
@Override
public byte[] getCipherText(int nextHeader, byte[] payload, int spi, int seqNum)
throws GeneralSecurityException {
final IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
final SecretKeySpec secretKeySpec = new SecretKeySpec(key, algoName);
final IvParameterSpec ivParameterSpec;
final SecretKeySpec secretKeySpec;
if (AES_CBC.equals(algoName)) {
ivParameterSpec = new IvParameterSpec(iv);
secretKeySpec = new SecretKeySpec(key, algoName);
} else if (AES_CTR.equals(algoName)) {
// Provided key consists of encryption/decryption key plus 4-byte salt. Salt is used
// with ESP payload IV and initial block counter value to build IvParameterSpec.
final byte[] secretKey = Arrays.copyOfRange(key, 0, key.length - saltLen);
final byte[] salt = Arrays.copyOfRange(key, secretKey.length, key.length);
secretKeySpec = new SecretKeySpec(secretKey, algoName);
final ByteBuffer ivParameterBuffer =
ByteBuffer.allocate(iv.length + saltLen + AES_CTR_INITIAL_COUNTER.length);
ivParameterBuffer.put(salt);
ivParameterBuffer.put(iv);
ivParameterBuffer.put(AES_CTR_INITIAL_COUNTER);
ivParameterSpec = new IvParameterSpec(ivParameterBuffer.array());
} else {
throw new IllegalArgumentException("Invalid algorithm " + algoName);
}
// Encrypt payload
final Cipher cipher = Cipher.getInstance(algoName);