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

Commit e0a046aa authored by Alex Klyubin's avatar Alex Klyubin Committed by Android Git Automerger
Browse files

am 656fd493: Merge "Make NONEwithECDSA truncate input when necessary." into mnc-dev

* commit '656fd493':
  Make NONEwithECDSA truncate input when necessary.
parents 9b013a5a 656fd493
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -363,8 +363,9 @@ abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreC

        @Override
        public byte[] doFinal(byte[] input, int inputOffset, int inputLength,
                byte[] additionalEntropy) throws KeyStoreException {
            byte[] output = mDelegate.doFinal(input, inputOffset, inputLength, additionalEntropy);
                byte[] signature, byte[] additionalEntropy) throws KeyStoreException {
            byte[] output = mDelegate.doFinal(input, inputOffset, inputLength, signature,
                    additionalEntropy);
            if (output != null) {
                try {
                    mBufferedOutput.write(output);
@@ -425,7 +426,7 @@ abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreC
        }

        @Override
        public OperationResult finish(byte[] additionalEntropy) {
        public OperationResult finish(byte[] signature, byte[] additionalEntropy) {
            if ((additionalEntropy != null) && (additionalEntropy.length > 0)) {
                throw new ProviderException("AAD stream does not support additional entropy");
            }
+5 −1
Original line number Diff line number Diff line
@@ -353,6 +353,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
            try {
                output = mAdditionalAuthenticationDataStreamer.doFinal(
                        EmptyArray.BYTE, 0, 0,
                        null, // no signature
                        null // no additional entropy needed flushing AAD
                        );
            } finally {
@@ -469,7 +470,10 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
            byte[] additionalEntropy =
                    KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
                            mRng, getAdditionalEntropyAmountForFinish());
            output = mMainDataStreamer.doFinal(input, inputOffset, inputLen, additionalEntropy);
            output = mMainDataStreamer.doFinal(
                    input, inputOffset, inputLen,
                    null, // no signature involved
                    additionalEntropy);
        } catch (KeyStoreException e) {
            switch (e.getErrorCode()) {
                case KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH:
+83 −6
Original line number Diff line number Diff line
@@ -17,11 +17,16 @@
package android.security.keystore;

import android.annotation.NonNull;
import android.os.IBinder;
import android.security.KeyStore;
import android.security.KeyStoreException;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;

import libcore.util.EmptyArray;

import java.io.ByteArrayOutputStream;
import java.security.InvalidKeyException;
import java.security.SignatureSpi;

@@ -36,6 +41,71 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature
        public NONE() {
            super(KeymasterDefs.KM_DIGEST_NONE);
        }

        @Override
        protected KeyStoreCryptoOperationStreamer createMainDataStreamer(KeyStore keyStore,
                IBinder operationToken) {
            return new TruncateToFieldSizeMessageStreamer(
                    super.createMainDataStreamer(keyStore, operationToken),
                    getGroupSizeBits());
        }

        /**
         * Streamer which buffers all input, then truncates it to field size, and then sends it into
         * KeyStore via the provided delegate streamer.
         */
        private static class TruncateToFieldSizeMessageStreamer
                implements KeyStoreCryptoOperationStreamer {

            private final KeyStoreCryptoOperationStreamer mDelegate;
            private final int mGroupSizeBits;
            private final ByteArrayOutputStream mInputBuffer = new ByteArrayOutputStream();
            private long mConsumedInputSizeBytes;

            private TruncateToFieldSizeMessageStreamer(
                    KeyStoreCryptoOperationStreamer delegate,
                    int groupSizeBits) {
                mDelegate = delegate;
                mGroupSizeBits = groupSizeBits;
            }

            @Override
            public byte[] update(byte[] input, int inputOffset, int inputLength)
                    throws KeyStoreException {
                if (inputLength > 0) {
                    mInputBuffer.write(input, inputOffset, inputLength);
                    mConsumedInputSizeBytes += inputLength;
                }
                return EmptyArray.BYTE;
            }

            @Override
            public byte[] doFinal(byte[] input, int inputOffset, int inputLength, byte[] signature,
                    byte[] additionalEntropy) throws KeyStoreException {
                if (inputLength > 0) {
                    mConsumedInputSizeBytes += inputLength;
                    mInputBuffer.write(input, inputOffset, inputLength);
                }

                byte[] bufferedInput = mInputBuffer.toByteArray();
                mInputBuffer.reset();
                // Truncate input at field size (bytes)
                return mDelegate.doFinal(bufferedInput,
                        0,
                        Math.min(bufferedInput.length, ((mGroupSizeBits + 7) / 8)),
                        signature, additionalEntropy);
            }

            @Override
            public long getConsumedInputSizeBytes() {
                return mConsumedInputSizeBytes;
            }

            @Override
            public long getProducedOutputSizeBytes() {
                return mDelegate.getProducedOutputSizeBytes();
            }
        }
    }

    public final static class SHA1 extends AndroidKeyStoreECDSASignatureSpi {
@@ -70,7 +140,7 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature

    private final int mKeymasterDigest;

    private int mGroupSizeBytes = -1;
    private int mGroupSizeBits = -1;

    AndroidKeyStoreECDSASignatureSpi(int keymasterDigest) {
        mKeymasterDigest = keymasterDigest;
@@ -95,14 +165,14 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature
        } else if (keySizeBits > Integer.MAX_VALUE) {
            throw new InvalidKeyException("Key too large: " + keySizeBits + " bits");
        }
        mGroupSizeBytes = (int) ((keySizeBits + 7) / 8);
        mGroupSizeBits = (int) keySizeBits;

        super.initKey(key);
    }

    @Override
    protected final void resetAll() {
        mGroupSizeBytes = -1;
        mGroupSizeBits = -1;
        super.resetAll();
    }

@@ -112,14 +182,21 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature
    }

    @Override
    protected void addAlgorithmSpecificParametersToBegin(
    protected final void addAlgorithmSpecificParametersToBegin(
            @NonNull KeymasterArguments keymasterArgs) {
        keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_EC);
        keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
    }

    @Override
    protected int getAdditionalEntropyAmountForSign() {
        return mGroupSizeBytes;
    protected final int getAdditionalEntropyAmountForSign() {
        return (mGroupSizeBits + 7) / 8;
    }

    protected final int getGroupSizeBits() {
        if (mGroupSizeBits == -1) {
            throw new IllegalStateException("Not initialized");
        }
        return mGroupSizeBits;
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -234,6 +234,7 @@ public abstract class AndroidKeyStoreHmacSpi extends MacSpi implements KeyStoreC
        try {
            result = mChunkedStreamer.doFinal(
                    null, 0, 0,
                    null, // no signature provided -- this invocation will generate one
                    null // no additional entropy needed -- HMAC is deterministic
                    );
        } catch (KeyStoreException e) {
+3 −3
Original line number Diff line number Diff line
@@ -150,8 +150,7 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase

            @Override
            public byte[] doFinal(byte[] input, int inputOffset, int inputLength,
                    byte[] additionalEntropy)
                    throws KeyStoreException {
                    byte[] signature, byte[] additionalEntropy) throws KeyStoreException {
                if (inputLength > 0) {
                    mConsumedInputSizeBytes += inputLength;
                    mInputBuffer.write(input, inputOffset, inputLength);
@@ -174,7 +173,8 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
                            "Message size (" + bufferedInput.length + " bytes) must be smaller than"
                            + " modulus (" + mModulusSizeBytes + " bytes)");
                }
                return mDelegate.doFinal(paddedInput, 0, paddedInput.length, additionalEntropy);
                return mDelegate.doFinal(paddedInput, 0, paddedInput.length, signature,
                        additionalEntropy);
            }

            @Override
Loading