diff --git a/src/main/java/com/google/crypto/tink/subtle/AesCtrHmacStreaming.java b/src/main/java/com/google/crypto/tink/subtle/AesCtrHmacStreaming.java index 0715e008..2ba1abe0 100644 --- a/src/main/java/com/google/crypto/tink/subtle/AesCtrHmacStreaming.java +++ b/src/main/java/com/google/crypto/tink/subtle/AesCtrHmacStreaming.java @@ -179,6 +179,9 @@ private static void validateParameters( throw new InvalidAlgorithmParameterException( "ikm too short, must be >= " + Math.max(16, keySizeInBytes)); } + if (firstSegmentOffset < 0) { + throw new InvalidAlgorithmParameterException("firstSegmentOffset must not be negative"); + } Validators.validateAesKeySize(keySizeInBytes); if (tagSizeInBytes < 10) { throw new InvalidAlgorithmParameterException("tag size too small " + tagSizeInBytes); diff --git a/src/test/java/com/google/crypto/tink/subtle/AesCtrHmacStreamingTest.java b/src/test/java/com/google/crypto/tink/subtle/AesCtrHmacStreamingTest.java index 4d80261e..7d57c5b5 100644 --- a/src/test/java/com/google/crypto/tink/subtle/AesCtrHmacStreamingTest.java +++ b/src/test/java/com/google/crypto/tink/subtle/AesCtrHmacStreamingTest.java @@ -256,6 +256,22 @@ public void testEncryptDecryptRandomAccessLastSegmentFull() throws Exception { testEncryptDecryptRandomAccess(16, 12, 256, 16, 440); } + @Test + public void testNegativeFirstSegmentOffset_throws() throws Exception { + byte[] ikm = Hex.decode("000102030405060708090a0b0c0d0e0f00112233445566778899aabbccddeeff"); + assertThrows( + GeneralSecurityException.class, + () -> + new AesCtrHmacStreaming( + ikm, + "HmacSha256", + /* keySizeInBytes= */ 16, + "HmacSha256", + /* tagSizeInBytes= */ 12, + /* ciphertextSegmentSize= */ 4096, + /* firstSegmentOffset= */ -1)); + } + /** * One case that is sometimes problematic is writing single bytes to a stream. This test * constructs an OutputStream from a WritableByteChannel and tests whether encryption works on