protected int engineDoFinal(
      byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
      throws IllegalBlockSizeException, BadPaddingException {
    int len = 0;

    if (inputLen != 0) {
      len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
    }

    try {
      return len + cipher.doFinal(output, outputOffset + len);
    } catch (DataLengthException e) {
      throw new IllegalBlockSizeException(e.getMessage());
    } catch (InvalidCipherTextException e) {
      throw new BadPaddingException(e.getMessage());
    }
  }
  protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
      throws IllegalBlockSizeException, BadPaddingException {
    int len = 0;
    byte[] tmp = new byte[engineGetOutputSize(inputLen)];

    if (inputLen != 0) {
      len = cipher.processBytes(input, inputOffset, inputLen, tmp, 0);
    }

    try {
      len += cipher.doFinal(tmp, len);
    } catch (DataLengthException e) {
      throw new IllegalBlockSizeException(e.getMessage());
    } catch (InvalidCipherTextException e) {
      throw new BadPaddingException(e.getMessage());
    }

    byte[] out = new byte[len];

    System.arraycopy(tmp, 0, out, 0, len);

    return out;
  }