Loading keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java +4 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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"); } Loading keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java +5 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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: Loading keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java +83 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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; Loading @@ -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(); } Loading @@ -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; } } keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java +1 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java +3 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 Loading
keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java +4 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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"); } Loading
keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java +5 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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: Loading
keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java +83 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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; Loading @@ -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(); } Loading @@ -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; } }
keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java +1 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading
keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java +3 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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