terl / lazysodium-java

A Java implementation of the Libsodium crypto library. For the lazy dev.

Home Page:https://github.com/terl/lazysodium-java/wiki

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How does paddedBuffLen in Sodium.sodium_pad() work?

erikvanzijst opened this issue · comments

The Sodium.sodium_pad native method declares the paddedBuffLen argument as a pass-by-value int.

    public native int sodium_pad(int paddedBuffLen, char[] buf, int unpaddedBufLen, int blockSize, int maxBufLen);

The documentation in Padding.Native states that paddedBuffLen is the new length of the buffer:

        /**
         * Adds extra padding to a buffer {@code buf} whose
         * original size is {@code unpaddedBufLen} in order
         * to extend its total length to a multiple of {@code blocksize}.
         * @param paddedBuffLen New length of buffer.
         * @param buf The buffer byte array.
         * @param unpaddedBufLen The length of {@code buf} with no padding.
         * @param blockSize Block size.
         * @param maxBufLen The absolute maximum you want this buffer length
         *                  to be.
         * @return False if the padded buffer length would exceed {@code maxBufLen}.
         */
        boolean sodiumPad(int paddedBuffLen, char[] buf, int unpaddedBufLen, int blockSize, int maxBufLen);

However, it seems that the C function takes a size_t pointer which it only writes a new value to.

int
sodium_pad(size_t *padded_buflen_p, unsigned char *buf,
           size_t unpadded_buflen, size_t blocksize, size_t max_buflen)

I might be overlooking something, but isn't the pointer used to communicate the padded length back to the caller? Something that doesn't work with Java's call-by-value primitives?

Hi @erikvanzijst I've changed the method signature to accept a Pointer rather than an int. Now if you look at the tests in PaddingTest, you can see how it works:

@Test
public void pad() {
    IntByReference ref = new IntByReference(0);
    char[] b = new char[4];

    lazySodium.sodiumPad(ref, b, 4, 4, 10);
    TestCase.assertEquals(8, ref.getValue());
}

Cool, thanks for the quick clarification and fix!