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

Commit 4ff2b3fd authored by Bo Zhu's avatar Bo Zhu
Browse files

Update the VaultParams encoding to reflect the recent change in the

format of vault_handle

Test: adb shell am instrument -w -e package
com.android.server.locksettings.recoverablekeystore
com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner

Change-Id: I105d17ac87b70795fa977b7649c7a1fdcb97b5e9
parent 1fc49dc6
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -174,8 +174,8 @@ public class KeySyncTask implements Runnable {
            return;
        }

        byte[] deviceId = mRecoverableKeyStoreDb.getServerParams(mUserId, recoveryAgentUid);
        if (deviceId == null) {
        byte[] vaultHandle = mRecoverableKeyStoreDb.getServerParams(mUserId, recoveryAgentUid);
        if (vaultHandle == null) {
            Log.w(TAG, "No device ID set for user " + mUserId);
            return;
        }
@@ -231,8 +231,8 @@ public class KeySyncTask implements Runnable {
        byte[] vaultParams = KeySyncUtils.packVaultParams(
                publicKey,
                counterId,
                deviceId,
                TRUSTED_HARDWARE_MAX_ATTEMPTS);
                TRUSTED_HARDWARE_MAX_ATTEMPTS,
                vaultHandle);

        byte[] encryptedRecoveryKey;
        try {
+6 −4
Original line number Diff line number Diff line
@@ -61,7 +61,8 @@ public class KeySyncUtils {
    private static final byte[] THM_KF_HASH_PREFIX = "THM_KF_hash".getBytes(StandardCharsets.UTF_8);

    private static final int KEY_CLAIMANT_LENGTH_BYTES = 16;
    private static final int VAULT_PARAMS_LENGTH_BYTES = 85;
    private static final int VAULT_PARAMS_LENGTH_BYTES = 94;
    private static final int VAULT_HANDLE_LENGTH_BYTES = 17;

    /**
     * Encrypts the recovery key using both the lock screen hash and the remote storage's public
@@ -287,18 +288,19 @@ public class KeySyncUtils {
     *
     * @param thmPublicKey Public key of the trusted hardware module.
     * @param counterId ID referring to the specific counter in the hardware module.
     * @param deviceId ID of the device.
     * @param maxAttempts Maximum allowed guesses before trusted hardware wipes key.
     * @param vaultHandle Handle of the Vault.
     * @return The binary vault params, ready for sync.
     */
    public static byte[] packVaultParams(
            PublicKey thmPublicKey, long counterId, byte[] deviceId, int maxAttempts) {
            PublicKey thmPublicKey, long counterId, int maxAttempts, byte[] vaultHandle) {
        // TODO: Check if vaultHandle has exactly the length of VAULT_HANDLE_LENGTH_BYTES somewhere
        return ByteBuffer.allocate(VAULT_PARAMS_LENGTH_BYTES)
                .order(ByteOrder.LITTLE_ENDIAN)
                .put(SecureBox.encodePublicKey(thmPublicKey))
                .putLong(counterId)
                .putLong(0L) // TODO: replace with device Id.
                .putInt(maxAttempts)
                .put(new byte[VAULT_HANDLE_LENGTH_BYTES]) // TODO: replace with real vaultHandle
                .array();
    }

+6 −6
Original line number Diff line number Diff line
@@ -77,8 +77,8 @@ public class KeySyncTaskTest {
    private static final int TEST_USER_ID = 1000;
    private static final int TEST_RECOVERY_AGENT_UID = 10009;
    private static final int TEST_RECOVERY_AGENT_UID2 = 10010;
    private static final byte[] TEST_DEVICE_ID =
            new byte[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2};
    private static final byte[] TEST_VAULT_HANDLE =
            new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, 16, 17};
    private static final String TEST_APP_KEY_ALIAS = "rcleaver";
    private static final int TEST_GENERATION_ID = 2;
    private static final int TEST_CREDENTIAL_TYPE = CREDENTIAL_TYPE_PASSWORD;
@@ -241,7 +241,7 @@ public class KeySyncTaskTest {
    public void run_doesNotSendAnythingIfNoRecoveryAgentPendingIntentRegistered() throws Exception {
        SecretKey applicationKey = generateKey();
        mRecoverableKeyStoreDb.setServerParams(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_DEVICE_ID);
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_VAULT_HANDLE);
        mRecoverableKeyStoreDb.setPlatformKeyGenerationId(TEST_USER_ID, TEST_GENERATION_ID);
        mRecoverableKeyStoreDb.insertKey(
                TEST_USER_ID,
@@ -300,8 +300,8 @@ public class KeySyncTaskTest {
                /*vaultParams=*/ KeySyncUtils.packVaultParams(
                        mKeyPair.getPublic(),
                        counterId,
                        TEST_DEVICE_ID,
                        /*maxAttempts=*/ 10));
                        /*maxAttempts=*/ 10,
                        TEST_VAULT_HANDLE));
        List<WrappedApplicationKey> applicationKeys = keychainSnapshot.getWrappedApplicationKeys();
        assertThat(applicationKeys).hasSize(1);
        WrappedApplicationKey keyData = applicationKeys.get(0);
@@ -471,7 +471,7 @@ public class KeySyncTaskTest {
            throws Exception{
        SecretKey applicationKey = generateKey();
        mRecoverableKeyStoreDb.setServerParams(
                userId, recoveryAgentUid, TEST_DEVICE_ID);
                userId, recoveryAgentUid, TEST_VAULT_HANDLE);
        mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, TEST_GENERATION_ID);

        // Newly added key is not synced.
+26 −25
Original line number Diff line number Diff line
@@ -50,8 +50,8 @@ public class KeySyncUtilsTest {
    private static final int RECOVERY_KEY_LENGTH_BITS = 256;
    private static final int THM_KF_HASH_SIZE = 256;
    private static final int KEY_CLAIMANT_LENGTH_BYTES = 16;
    private static final byte[] TEST_DEVICE_ID =
            new byte[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2};
    private static final byte[] TEST_VAULT_HANDLE =
            new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, 16, 17};
    private static final String SHA_256_ALGORITHM = "SHA-256";
    private static final String APPLICATION_KEY_ALGORITHM = "AES";
    private static final byte[] LOCK_SCREEN_HASH_1 =
@@ -63,7 +63,8 @@ public class KeySyncUtilsTest {
    private static final byte[] RECOVERY_RESPONSE_HEADER =
            "V1 reencrypted_recovery_key".getBytes(StandardCharsets.UTF_8);
    private static final int PUBLIC_KEY_LENGTH_BYTES = 65;
    private static final int VAULT_PARAMS_LENGTH_BYTES = 85;
    private static final int VAULT_PARAMS_LENGTH_BYTES = 94;
    private static final int VAULT_HANDLE_LENGTH_BYTES = 17;

    @Test
    public void calculateThmKfHash_isShaOfLockScreenHashWithPrefix() throws Exception {
@@ -344,14 +345,14 @@ public class KeySyncUtilsTest {
    }

    @Test
    public void packVaultParams_returns85Bytes() throws Exception {
    public void packVaultParams_returns94Bytes() throws Exception {
        PublicKey thmPublicKey = SecureBox.genKeyPair().getPublic();

        byte[] packedForm = KeySyncUtils.packVaultParams(
                thmPublicKey,
                /*counterId=*/ 1001L,
                TEST_DEVICE_ID,
                /*maxAttempts=*/ 10);
                /*maxAttempts=*/ 10,
                TEST_VAULT_HANDLE);

        assertEquals(VAULT_PARAMS_LENGTH_BYTES, packedForm.length);
    }
@@ -363,8 +364,8 @@ public class KeySyncUtilsTest {
        byte[] packedForm = KeySyncUtils.packVaultParams(
                thmPublicKey,
                /*counterId=*/ 1001L,
                TEST_DEVICE_ID,
                /*maxAttempts=*/ 10);
                /*maxAttempts=*/ 10,
                TEST_VAULT_HANDLE);

        assertArrayEquals(
                SecureBox.encodePublicKey(thmPublicKey),
@@ -378,8 +379,8 @@ public class KeySyncUtilsTest {
        byte[] packedForm = KeySyncUtils.packVaultParams(
                SecureBox.genKeyPair().getPublic(),
                counterId,
                TEST_DEVICE_ID,
                /*maxAttempts=*/ 10);
                /*maxAttempts=*/ 10,
                TEST_VAULT_HANDLE);

        ByteBuffer byteBuffer = ByteBuffer.wrap(packedForm)
                .order(ByteOrder.LITTLE_ENDIAN);
@@ -388,38 +389,38 @@ public class KeySyncUtilsTest {
    }

    @Test
    public void packVaultParams_encodesDeviceIdAsThirdParam() throws Exception {
    public void packVaultParams_encodesMaxAttemptsAsThirdParam() throws Exception {
        int maxAttempts = 10;

        byte[] packedForm = KeySyncUtils.packVaultParams(
                SecureBox.genKeyPair().getPublic(),
                /*counterId=*/ 10021L,
                TEST_DEVICE_ID,
                /*maxAttempts=*/ 10);
                /*counterId=*/ 1001L,
                maxAttempts,
                TEST_VAULT_HANDLE);

        ByteBuffer byteBuffer = ByteBuffer.wrap(packedForm)
                .order(ByteOrder.LITTLE_ENDIAN);
        byteBuffer.position(PUBLIC_KEY_LENGTH_BYTES + Long.BYTES);
        assertEquals(/* default value*/0, byteBuffer.getLong());
        assertEquals(maxAttempts, byteBuffer.getInt());
    }

    @Test
    public void packVaultParams_encodesMaxAttemptsAsLastParam() throws Exception {
        int maxAttempts = 10;

    public void packVaultParams_encodesVaultHandleAsLastParam() throws Exception {
        byte[] packedForm = KeySyncUtils.packVaultParams(
                SecureBox.genKeyPair().getPublic(),
                /*counterId=*/ 1001L,
                TEST_DEVICE_ID,
                maxAttempts);
                /*counterId=*/ 10021L,
                /*maxAttempts=*/ 10,
                TEST_VAULT_HANDLE);

        ByteBuffer byteBuffer = ByteBuffer.wrap(packedForm)
                .order(ByteOrder.LITTLE_ENDIAN);
        // TODO: update position.
        byteBuffer.position(PUBLIC_KEY_LENGTH_BYTES + 2 * Long.BYTES);
        assertEquals(maxAttempts, byteBuffer.getInt());
        byteBuffer.position(PUBLIC_KEY_LENGTH_BYTES + Long.BYTES + Integer.BYTES);
        byte[] vaultHandle = new byte[VAULT_HANDLE_LENGTH_BYTES];
        byteBuffer.get(vaultHandle);
        // TODO: Fix this once we fix the code in the KeySyncUtils class
        assertArrayEquals(new byte[VAULT_HANDLE_LENGTH_BYTES], vaultHandle);
    }


    private static byte[] randomBytes(int n) {
        byte[] bytes = new byte[n];
        new Random().nextBytes(bytes);