diff options
| author | 2021-09-23 16:56:06 -0700 | |
|---|---|---|
| committer | 2021-09-24 10:19:04 -0700 | |
| commit | 395e56a71c87d3748ca280f235da04983069de87 (patch) | |
| tree | 21de6ed121316223a0b07e4a3a50a5c92fa932df | |
| parent | f4c5136dbfb879baac23a5fdfcf4494154f12fa3 (diff) | |
DO NOT MERGE KeyStore ChunkedStreamer must tolerate update consuming 0 bytes.
Some older versions of Keymster do not consume any data in certain block
modes unless a full block of data was presented.
Bug: 199032140
Bug: 200041882
Test: CtsKeyStoreTestcases with KM1.0 backend.
Merged-In: Ic2da6e5c12628f11603f51c7a3408aad70947d95
Change-Id: Ic2da6e5c12628f11603f51c7a3408aad70947d95
| -rw-r--r-- | keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java index 2c0f40d528d2..cedc4d2fb8e6 100644 --- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java +++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java @@ -126,8 +126,8 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS if (mChunkLength > mChunkSizeMax) { throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH, - "Chunk size exceeded max chunk size. Max: " + mChunkSizeMax - + " Actual: " + mChunkLength); + "Chunk size exceeded max chunk size. Max: " + mChunkSizeMax + + " Actual: " + mChunkLength); } if (mChunkLength >= mChunkSizeThreshold) { @@ -139,18 +139,28 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS } else if (opResult.resultCode != KeyStore.NO_ERROR) { throw KeyStore.getKeyStoreException(opResult.resultCode); } - if (opResult.inputConsumed <= 0) { - throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH, - "Keystore consumed 0 of " + mChunkLength + " bytes provided."); - } else if (opResult.inputConsumed > mChunkLength) { + if (opResult.inputConsumed == 0) { + // Some KM implementations do not consume data in certain block modes unless a + // full block of data was presented. + if (inputLength > 0) { + // More input is available, but it wasn't included into the previous chunk + // because the chunk reached its maximum permitted size. + // Shouldn't have happened. + throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH, + "Keystore consumed nothing from max-sized chunk: " + mChunkLength + + " bytes"); + } + } else if (opResult.inputConsumed > mChunkLength || opResult.inputConsumed < 0) { throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR, - "Keystore consumed more input than provided. Provided: " - + mChunkLength + ", consumed: " + opResult.inputConsumed); + "Keystore consumed more input than provided (or inputConsumed was " + + "negative." + + " Provided: " + mChunkLength + + ", consumed: " + opResult.inputConsumed); } mChunkLength -= opResult.inputConsumed; if (mChunkLength > 0) { - // Partialy consumed, shift chunk contents + // Partially consumed, shift chunk contents ArrayUtils.copy(mChunk, opResult.inputConsumed, mChunk, 0, mChunkLength); } |