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

Commit d976c5a4 authored by Alex Klyubin's avatar Alex Klyubin
Browse files

Custom engineUpdate/engineDoFinal(ByteBuffer, ByteBuffer).

This makes Android Keystore's Cipher implementation use a custom
implementation of engineUpdate(ByteBuffer, ByteBuffer) and
engineDoFinal(ByteBuffer, ByteBuffer). The implementation is
explicitly designed around the fact that Android Keystore transmits
input and receives output via Binder and thus there's no need to
attempt any optimizations to avoid copying input and output.

Bug: 25863382
Change-Id: I311072891f02f5e7a283628b51b8d6058b55231c
parent 9a83f115
Loading
Loading
Loading
Loading
+65 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.security.keymaster.OperationResult;

import libcore.util.EmptyArray;

import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
@@ -385,7 +386,38 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
    @Override
    protected final int engineUpdate(ByteBuffer input, ByteBuffer output)
            throws ShortBufferException {
        return super.engineUpdate(input, output);
        if (input == null) {
            throw new NullPointerException("input == null");
        }
        if (output == null) {
            throw new NullPointerException("output == null");
        }

        int inputSize = input.remaining();
        byte[] outputArray;
        if (input.hasArray()) {
            outputArray =
                    engineUpdate(
                            input.array(), input.arrayOffset() + input.position(), inputSize);
            input.position(input.position() + inputSize);
        } else {
            byte[] inputArray = new byte[inputSize];
            input.get(inputArray);
            outputArray = engineUpdate(inputArray, 0, inputSize);
        }

        int outputSize = (outputArray != null) ? outputArray.length : 0;
        if (outputSize > 0) {
            int outputBufferAvailable = output.remaining();
            try {
                output.put(outputArray);
            } catch (BufferOverflowException e) {
                throw new ShortBufferException(
                        "Output buffer too small. Produced: " + outputSize + ", available: "
                                + outputBufferAvailable);
            }
        }
        return outputSize;
    }

    @Override
@@ -511,7 +543,38 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
    @Override
    protected final int engineDoFinal(ByteBuffer input, ByteBuffer output)
            throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
        return super.engineDoFinal(input, output);
        if (input == null) {
            throw new NullPointerException("input == null");
        }
        if (output == null) {
            throw new NullPointerException("output == null");
        }

        int inputSize = input.remaining();
        byte[] outputArray;
        if (input.hasArray()) {
            outputArray =
                    engineDoFinal(
                            input.array(), input.arrayOffset() + input.position(), inputSize);
            input.position(input.position() + inputSize);
        } else {
            byte[] inputArray = new byte[inputSize];
            input.get(inputArray);
            outputArray = engineDoFinal(inputArray, 0, inputSize);
        }

        int outputSize = (outputArray != null) ? outputArray.length : 0;
        if (outputSize > 0) {
            int outputBufferAvailable = output.remaining();
            try {
                output.put(outputArray);
            } catch (BufferOverflowException e) {
                throw new ShortBufferException(
                        "Output buffer too small. Produced: " + outputSize + ", available: "
                                + outputBufferAvailable);
            }
        }
        return outputSize;
    }

    @Override