public int doFinal()

in src/main/java/org/apache/commons/crypto/cipher/OpenSslGaloisCounterMode.java [62:117]


    public int doFinal(final byte[] input, final int inputOffset, final int inputLen, final byte[] output, final int outputOffset)
            throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
        checkState();

        processAAD();

        final int outputLength = output.length;
        int len;
        if (this.cipherMode == OpenSsl.DECRYPT_MODE) {
            // if GCM-DECRYPT, we have to handle the buffered input
            // and the retrieve the trailing tag from input
            int inputOffsetFinal = inputOffset;
            int inputLenFinal = inputLen;
            final byte[] inputFinal;
            if (inBuffer != null && inBuffer.size() > 0) {
                inBuffer.write(input, inputOffset, inputLen);
                inputFinal = inBuffer.toByteArray();
                inputOffsetFinal = 0;
                inputLenFinal = inputFinal.length;
                inBuffer.reset();
            } else {
                inputFinal = input;
            }

            if (inputFinal.length < getTagLen()) {
                throw new AEADBadTagException("Input too short - need tag");
            }

            final int inputDataLen = inputLenFinal - getTagLen();
            len = OpenSslNative.updateByteArray(context, inputFinal, inputOffsetFinal,
                    inputDataLen, output, outputOffset, outputLength - outputOffset);

            // set tag to EVP_Cipher for integrity verification in doFinal
            final ByteBuffer tag = ByteBuffer.allocate(getTagLen());
            tag.put(input, input.length - getTagLen(), getTagLen());
            tag.flip();
            evpCipherCtxCtrl(context, OpenSslEvpCtrlValues.AEAD_SET_TAG.getValue(), getTagLen(), tag);
        } else {
            len = OpenSslNative.updateByteArray(context, input, inputOffset,
                    inputLen, output, outputOffset, outputLength - outputOffset);
        }

        len += OpenSslNative.doFinalByteArray(context, output, outputOffset + len,
                outputLength - outputOffset - len);

        // Keep the similar behavior as JCE, append the tag to end of output
        if (this.cipherMode == OpenSsl.ENCRYPT_MODE) {
            final ByteBuffer tag;
            tag = ByteBuffer.allocate(getTagLen());
            evpCipherCtxCtrl(context, OpenSslEvpCtrlValues.AEAD_GET_TAG.getValue(), getTagLen(), tag);
            tag.get(output, outputLength - getTagLen(), getTagLen());
            len += getTagLen();
        }

        return len;
    }