Loading services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java +4 −4 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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 { Loading services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java +6 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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(); } Loading services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java +6 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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. Loading services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncUtilsTest.java +26 −25 Original line number Diff line number Diff line Loading @@ -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 = Loading @@ -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 { Loading Loading @@ -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); } Loading @@ -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), Loading @@ -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); Loading @@ -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); Loading Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java +4 −4 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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 { Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java +6 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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(); } Loading
services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java +6 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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. Loading
services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncUtilsTest.java +26 −25 Original line number Diff line number Diff line Loading @@ -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 = Loading @@ -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 { Loading Loading @@ -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); } Loading @@ -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), Loading @@ -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); Loading @@ -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); Loading