diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java index 95e88d712f55f..a29e1be0fdcae 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java @@ -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 { diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java index b4bef170e2bca..219f6e10938e4 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java @@ -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(); } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java index f34017812651b..c6fc675db6b15 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java @@ -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 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. diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncUtilsTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncUtilsTest.java index 3a9ff85520ffb..ba6b274b83b89 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncUtilsTest.java @@ -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,37 +389,37 @@ public class KeySyncUtilsTest { } @Test - public void packVaultParams_encodesDeviceIdAsThirdParam() throws Exception { - - byte[] packedForm = KeySyncUtils.packVaultParams( - SecureBox.genKeyPair().getPublic(), - /*counterId=*/ 10021L, - TEST_DEVICE_ID, - /*maxAttempts=*/ 10); - - ByteBuffer byteBuffer = ByteBuffer.wrap(packedForm) - .order(ByteOrder.LITTLE_ENDIAN); - byteBuffer.position(PUBLIC_KEY_LENGTH_BYTES + Long.BYTES); - assertEquals(/* default value*/0, byteBuffer.getLong()); - } - - @Test - public void packVaultParams_encodesMaxAttemptsAsLastParam() throws Exception { + public void packVaultParams_encodesMaxAttemptsAsThirdParam() throws Exception { int maxAttempts = 10; byte[] packedForm = KeySyncUtils.packVaultParams( SecureBox.genKeyPair().getPublic(), /*counterId=*/ 1001L, - TEST_DEVICE_ID, - maxAttempts); + maxAttempts, + TEST_VAULT_HANDLE); ByteBuffer byteBuffer = ByteBuffer.wrap(packedForm) .order(ByteOrder.LITTLE_ENDIAN); - // TODO: update position. - byteBuffer.position(PUBLIC_KEY_LENGTH_BYTES + 2 * Long.BYTES); + byteBuffer.position(PUBLIC_KEY_LENGTH_BYTES + Long.BYTES); assertEquals(maxAttempts, byteBuffer.getInt()); } + @Test + public void packVaultParams_encodesVaultHandleAsLastParam() throws Exception { + byte[] packedForm = KeySyncUtils.packVaultParams( + SecureBox.genKeyPair().getPublic(), + /*counterId=*/ 10021L, + /*maxAttempts=*/ 10, + TEST_VAULT_HANDLE); + + ByteBuffer byteBuffer = ByteBuffer.wrap(packedForm) + .order(ByteOrder.LITTLE_ENDIAN); + 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];