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

Commit 838d33b4 authored by Eric Biggers's avatar Eric Biggers
Browse files

locksettings: use ArrayUtils.concat(byte[]...)

Use the new byte array concatenation utility method where appropriate.

No change in behavior intended; this is just a cleanup.  The new method
accepts null arrays, whereas most of the previous workarounds didn't,
but I don't see anywhere where this would make a difference.

Also use HexEncoding.encodeToString() in a couple places.

Test: atest com.android.server.locksettings
Test: atest LockscreenCredentialTest
Change-Id: I203018d7cba2721a9d0c4988708df7147e396dbe
parent 4dd9540f
Loading
Loading
Loading
Loading
+4 −12
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.os.Parcelable;
import android.os.storage.StorageManager;
import android.text.TextUtils;

import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;

import libcore.util.HexEncoding;
@@ -280,7 +281,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
            sha256.update(hashFactor);
            sha256.update(passwordToHash);
            sha256.update(salt);
            return new String(HexEncoding.encode(sha256.digest()));
            return HexEncoding.encodeToString(sha256.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError("Missing digest algorithm: ", e);
        }
@@ -302,21 +303,12 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
        }

        try {
            // Previously the password was passed as a String with the following code:
            // byte[] saltedPassword = (password + salt).getBytes();
            // The code below creates the identical digest preimage using byte arrays:
            byte[] saltedPassword = Arrays.copyOf(password, password.length + salt.length);
            System.arraycopy(salt, 0, saltedPassword, password.length, salt.length);
            byte[] saltedPassword = ArrayUtils.concat(password, salt);
            byte[] sha1 = MessageDigest.getInstance("SHA-1").digest(saltedPassword);
            byte[] md5 = MessageDigest.getInstance("MD5").digest(saltedPassword);

            byte[] combined = new byte[sha1.length + md5.length];
            System.arraycopy(sha1, 0, combined, 0, sha1.length);
            System.arraycopy(md5, 0, combined, sha1.length, md5.length);

            final char[] hexEncoded = HexEncoding.encode(combined);
            Arrays.fill(saltedPassword, (byte) 0);
            return new String(hexEncoded);
            return HexEncoding.encodeToString(ArrayUtils.concat(sha1, md5));
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError("Missing digest algorithm: ", e);
        }
+7 −14
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
@@ -147,7 +148,6 @@ import com.android.server.wm.WindowManagerInternal;

import libcore.util.HexEncoding;

import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -1847,8 +1847,8 @@ public class LockSettingsService extends ILockSettings.Stub {
    @VisibleForTesting /** Note: this method is overridden in unit tests */
    protected void tieProfileLockToParent(int userId, LockscreenCredential password) {
        if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
        byte[] encryptionResult;
        byte[] iv;
        final byte[] iv;
        final byte[] ciphertext;
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
            keyGenerator.init(new SecureRandom());
@@ -1877,7 +1877,7 @@ public class LockSettingsService extends ILockSettings.Stub {
                        KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
                                + KeyProperties.ENCRYPTION_PADDING_NONE);
                cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
                encryptionResult = cipher.doFinal(password.getCredential());
                ciphertext = cipher.doFinal(password.getCredential());
                iv = cipher.getIV();
            } finally {
                // The original key can now be discarded.
@@ -1888,17 +1888,10 @@ public class LockSettingsService extends ILockSettings.Stub {
                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new IllegalStateException("Failed to encrypt key", e);
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
        if (iv.length != PROFILE_KEY_IV_SIZE) {
            throw new IllegalArgumentException("Invalid iv length: " + iv.length);
        }
            outputStream.write(iv);
            outputStream.write(encryptionResult);
        } catch (IOException e) {
            throw new IllegalStateException("Failed to concatenate byte arrays", e);
        }
        mStorage.writeChildProfileLock(userId, outputStream.toByteArray());
        mStorage.writeChildProfileLock(userId, ArrayUtils.concat(iv, ciphertext));
    }

    private void setUserKeyProtection(int userId, byte[] key) {
+2 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.security.keystore.UserNotAuthenticatedException;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockscreenCredential;

import java.security.GeneralSecurityException;
@@ -117,8 +118,7 @@ public class ManagedProfilePasswordCache {
                cipher.init(Cipher.ENCRYPT_MODE, key);
                byte[] ciphertext = cipher.doFinal(password.getCredential());
                byte[] iv = cipher.getIV();
                byte[] block = Arrays.copyOf(iv, ciphertext.length + iv.length);
                System.arraycopy(ciphertext, 0, block, iv.length, ciphertext.length);
                byte[] block = ArrayUtils.concat(iv, ciphertext);
                mEncryptedPasswords.put(userId, block);
            } catch (GeneralSecurityException e) {
                Slog.d(TAG, "Cannot encrypt", e);
+3 −5
Original line number Diff line number Diff line
@@ -25,7 +25,8 @@ import android.system.keystore2.Domain;
import android.system.keystore2.KeyDescriptor;
import android.util.Slog;

import java.io.ByteArrayOutputStream;
import com.android.internal.util.ArrayUtils;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
@@ -94,10 +95,7 @@ public class SyntheticPasswordCrypto {
        if (spec.getTLen() != DEFAULT_TAG_LENGTH_BITS) {
            throw new IllegalArgumentException("Invalid tag length: " + spec.getTLen());
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        outputStream.write(iv);
        outputStream.write(ciphertext);
        return outputStream.toByteArray();
        return ArrayUtils.concat(iv, ciphertext);
    }

    public static byte[] encrypt(byte[] keyBytes, byte[] personalization, byte[] message) {
+2 −8
Original line number Diff line number Diff line
@@ -1347,19 +1347,13 @@ public class SyntheticPasswordManager {
    private byte[] transformUnderWeaverSecret(byte[] data, byte[] secret) {
        byte[] weaverSecret = SyntheticPasswordCrypto.personalizedHash(
                PERSONALIZATION_WEAVER_PASSWORD, secret);
        byte[] result = new byte[data.length + weaverSecret.length];
        System.arraycopy(data, 0, result, 0, data.length);
        System.arraycopy(weaverSecret, 0, result, data.length, weaverSecret.length);
        return result;
        return ArrayUtils.concat(data, weaverSecret);
    }

    private byte[] transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable) {
        byte[] secdiscardable = SyntheticPasswordCrypto.personalizedHash(
                PERSONALIZATION_SECDISCARDABLE, rawSecdiscardable);
        byte[] result = new byte[data.length + secdiscardable.length];
        System.arraycopy(data, 0, result, 0, data.length);
        System.arraycopy(secdiscardable, 0, result, data.length, secdiscardable.length);
        return result;
        return ArrayUtils.concat(data, secdiscardable);
    }

    private byte[] createSecdiscardable(long protectorId, int userId) {
Loading