On Mon, 2 Nov 2020 22:30:45 GMT, Anthony Scarpino <[email protected]> wrote:
>>> * It was my expectation that checkOutputCapacity() is making sure all
>>> the inOfs ==<> outOfs are going to work. Does that not catch all cases?
>> checkOutputCapacity() as the name has, only changes that the output buffer
>> is large enough.
>>
>>> * outWithPadding" is excessive because it doubles the allocation for
>>> every operation followed by a copy to the original buffer, even if the
>>> original buffer was adequate. I'm ok with doing the extra alloc & copy in
>>> certain situations, but not everytime. Can you be more specific what
>>> things may fail that we don't already check for in the regression tests?
>>
>> For example,
>> 1) various input/output offset combinations, e.g. inOfs <,=,> outOfs,
>> 2) Given a output buffer of 200-byte and outOfs == 0, assuming the returned
>> decrypted data length is 160 bytes, the bytes from index 160 and onward
>> should not be overwritten. GCM has no padding, so you may not notice any
>> difference if this is what you are testing. This is generic CipherCore code
>> and changes impact all ciphers.
>
> checkOutputCapacity: Yes.. The method includes the offsets for the output
> buffer, which I believe would verify that the output area in the buffer with
> offsets is large enough.
>
> outWithPadding: I understand the situation and I am assuming there are tests
> that cover this case. Given it's a generic situation.
Have you tested the outWithPadding situation? Given that the existing impl only
write out the final result, I don't think you can assume that existing tests
cover it. I have wrote a simple test to check it if you have not done so, can
you try it out to be sure?
import java.io.PrintStream;
import java.util.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class TestDoFinal {
private static String ALGO = "AES";
private static int BLK_SIZE = 16;
public static void main(String args[]) throws Exception {
byte[] in = new byte[32];
Arrays.fill(in, (byte)8);
KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
SecretKey skey = kg.generateKey();
Cipher ci = Cipher.getInstance(ALGO + "/CBC/PKCS5Padding", "SunJCE");
ci.init(Cipher.ENCRYPT_MODE, skey);
int inLen = in.length - BLK_SIZE;
byte[] out = ci.doFinal(in, 0, inLen);
System.out.println("=> enc " + inLen + " bytes, ret " +
(out == null? "null":(out.length + " byte")));
AlgorithmParameters param = ci.getParameters();
ci.init(Cipher.DECRYPT_MODE, skey, param);
int rLen = ci.doFinal(out, 0, out.length, in);
System.out.println("=> dec " + out.length + " bytes, ret " +
rLen + " byte");
// check if more than rLen bytes are written into 'in'
for (int j = rLen; j < in.length; j++) {
if (in[j] != (byte)8) {
throw new Exception("Value check failed at index " + j);
}
}
System.out.println("Test Passed");
}
}
-------------
PR: https://git.openjdk.java.net/jdk/pull/411