On Mon, 2 Nov 2020 22:30:45 GMT, Anthony Scarpino <ascarp...@openjdk.org> 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

Reply via email to