|
3 | 3 | import java.security.SecureRandom; |
4 | 4 |
|
5 | 5 | import org.bouncycastle.crypto.InvalidCipherTextException; |
| 6 | +import org.bouncycastle.crypto.engines.AESEngine; |
6 | 7 | import org.bouncycastle.crypto.macs.SipHash; |
| 8 | +import org.bouncycastle.crypto.modes.CTSBlockCipher; |
7 | 9 | import org.bouncycastle.crypto.modes.ChaCha20Poly1305; |
8 | 10 | import org.bouncycastle.crypto.params.AEADParameters; |
9 | 11 | import org.bouncycastle.crypto.params.KeyParameter; |
| 12 | +import org.bouncycastle.util.Arrays; |
10 | 13 | import org.bouncycastle.util.Strings; |
11 | 14 | import org.bouncycastle.util.Times; |
12 | 15 | import org.bouncycastle.util.encoders.Hex; |
@@ -48,6 +51,7 @@ public String getName() |
48 | 51 |
|
49 | 52 | public void performTest() throws Exception |
50 | 53 | { |
| 54 | + testOverlapping(); |
51 | 55 | for (int i = 0; i < TEST_VECTORS.length; ++i) |
52 | 56 | { |
53 | 57 | runTestCase(TEST_VECTORS[i]); |
@@ -439,6 +443,55 @@ private void testExceptions() throws InvalidCipherTextException |
439 | 443 | } |
440 | 444 | } |
441 | 445 |
|
| 446 | + private void testOverlapping() |
| 447 | + throws Exception |
| 448 | + { |
| 449 | + SecureRandom random = new SecureRandom(); |
| 450 | + int kLength = 32; |
| 451 | + byte[] K = new byte[kLength]; |
| 452 | + random.nextBytes(K); |
| 453 | + |
| 454 | + int aLength = random.nextInt() >>> 24; |
| 455 | + byte[] A = new byte[aLength]; |
| 456 | + random.nextBytes(A); |
| 457 | + |
| 458 | + int nonceLength = 12; |
| 459 | + byte[] nonce = new byte[nonceLength]; |
| 460 | + random.nextBytes(nonce); |
| 461 | + |
| 462 | + AEADParameters parameters = new AEADParameters(new KeyParameter(K), 16 * 8, nonce, A); |
| 463 | + |
| 464 | + ChaCha20Poly1305 bc = initCipher(true, parameters); |
| 465 | + |
| 466 | + final int blockSize = 64; |
| 467 | + int offset = 1 + random.nextInt(blockSize - 1) + blockSize; |
| 468 | + byte[] data = new byte[blockSize * 4 + offset]; |
| 469 | + byte[] expected = new byte[bc.getOutputSize(blockSize * 3)]; |
| 470 | + random.nextBytes(data); |
| 471 | + |
| 472 | + |
| 473 | + int len = bc.processBytes(data, 0, blockSize * 3, expected, 0); |
| 474 | + bc.doFinal(expected, len); |
| 475 | + bc = initCipher(true, parameters); |
| 476 | + len = bc.processBytes(data, 0, blockSize * 3, data, offset); |
| 477 | + bc.doFinal(data, offset + len); |
| 478 | + |
| 479 | + if (!areEqual(expected, Arrays.copyOfRange(data, offset, offset + expected.length))) |
| 480 | + { |
| 481 | + fail("failed to overlapping of encryption"); |
| 482 | + } |
| 483 | + |
| 484 | + bc = initCipher(false, parameters); |
| 485 | + bc.processBytes(data, 0, expected.length, expected, 0); |
| 486 | + bc = initCipher(true, parameters); |
| 487 | + bc.processBytes(data, 0, expected.length, data, offset); |
| 488 | + |
| 489 | + if (!areEqual(expected, Arrays.copyOfRange(data, offset, offset + expected.length))) |
| 490 | + { |
| 491 | + fail("failed to overlapping of encryption"); |
| 492 | + } |
| 493 | + } |
| 494 | + |
442 | 495 | public static void main(String[] args) |
443 | 496 | { |
444 | 497 | runTest(new ChaCha20Poly1305Test()); |
|
0 commit comments