public void changeSendCipher(BlockCipher bc, MAC mac) {
    if ((bc instanceof NullCipher) == false) {
      /* Only use zero byte padding for the first few packets */
      useRandomPadding = true;
      /* Once we start encrypting, there is no way back */
    }

    cos.changeCipher(bc);
    send_mac = mac;
    send_mac_buffer = (mac != null) ? new byte[mac.size()] : null;
    send_padd_blocksize = bc.getBlockSize();
    if (send_padd_blocksize < 8) send_padd_blocksize = 8;
  }
  public void sendMessage(byte[] message, int off, int len, int padd) throws IOException {
    if (padd < 4) padd = 4;
    else if (padd > 64) padd = 64;

    int packet_len = 5 + len + padd; /* Minimum allowed padding is 4 */

    int slack = packet_len % send_padd_blocksize;

    if (slack != 0) {
      packet_len += (send_padd_blocksize - slack);
    }

    if (packet_len < 16) packet_len = 16;

    int padd_len = packet_len - (5 + len);

    if (useRandomPadding) {
      for (int i = 0; i < padd_len; i = i + 4) {
        /*
         * don't waste calls to rnd.nextInt() (by using only 8bit of the
         * output). just believe me: even though we may write here up to 3
         * bytes which won't be used, there is no "buffer overflow" (i.e.,
         * arrayindexoutofbounds). the padding buffer is big enough =) (256
         * bytes, and that is bigger than any current cipher block size + 64).
         */

        int r = rnd.nextInt();
        send_padding_buffer[i] = (byte) r;
        send_padding_buffer[i + 1] = (byte) (r >> 8);
        send_padding_buffer[i + 2] = (byte) (r >> 16);
        send_padding_buffer[i + 3] = (byte) (r >> 24);
      }
    } else {
      /* use zero padding for unencrypted traffic */
      for (int i = 0; i < padd_len; i++) send_padding_buffer[i] = 0;
      /* Actually this code is paranoid: we never filled any
       * bytes into the padding buffer so far, therefore it should
       * consist of zeros only.
       */
    }

    send_packet_header_buffer[0] = (byte) ((packet_len - 4) >> 24);
    send_packet_header_buffer[1] = (byte) ((packet_len - 4) >> 16);
    send_packet_header_buffer[2] = (byte) ((packet_len - 4) >> 8);
    send_packet_header_buffer[3] = (byte) ((packet_len - 4));
    send_packet_header_buffer[4] = (byte) padd_len;

    cos.write(send_packet_header_buffer, 0, 5);
    cos.write(message, off, len);
    cos.write(send_padding_buffer, 0, padd_len);

    if (send_mac != null) {
      send_mac.initMac(send_seq_number);
      send_mac.update(send_packet_header_buffer, 0, 5);
      send_mac.update(message, off, len);
      send_mac.update(send_padding_buffer, 0, padd_len);

      send_mac.getMac(send_mac_buffer, 0);
      cos.writePlain(send_mac_buffer, 0, send_mac_buffer.length);
    }

    cos.flush();

    if (log.isEnabled()) {
      log.log(
          90, "Sent " + Packets.getMessageName(message[off] & 0xff) + " " + len + " bytes payload");
    }

    send_seq_number++;
  }