<commit_before>package com.enigmabridge.comm;

import com.enigmabridge.EBCommKeys;
import com.enigmabridge.EBCryptoException;
import com.enigmabridge.EBEngineException;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.engines.AESLightEngine;
import org.bouncycastle.crypto.macs.CBCBlockCipherMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Arrays;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * Process data cipher.
 * Encrypt-then-MAC.
 *
 * AES-256/CBC/PKCS7 + HMAC/AES-256/CBC
 *
 * Created by dusanklinec on 26.04.16.
 */
public class EBProcessDataCipher {
    public static final String PROCESS_DATA_CIPHER = "ProcessDataV1";
    public static final byte[] ZERO_IV = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    protected boolean forEncryption;
    protected Cipher enc;
    protected Mac mac;
    protected int macSize;

    public EBProcessDataCipher(boolean forEncryption, Cipher enc, Mac mac) {
        this.forEncryption = forEncryption;
        this.enc = enc;
        this.mac = mac;
        this.macSize = mac.getMacSize();
    }

    /**
     * Creates a new cipher instance with given keys.
     * @param forEncryption
     * @param keys
     * @return
     */
    public static EBProcessDataCipher initCipher(boolean forEncryption, EBCommKeys keys) throws EBEngineException {
        try {
            // Initialize cipher
            final Cipher enc = Cipher.getInstance("AES/CBC/PKCS5Padding");
            enc.init(
                    forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE,
                    new SecretKeySpec(keys.getEncKey(), "AES"),
                    new IvParameterSpec(ZERO_IV));

            // Initialize CBC MAC.
            // There is no AES-CBC-MAC in the BouncyCastle provider.
            final BlockCipher cipher = new AESLightEngine();
            final CBCBlockCipherMac mac = new CBCBlockCipherMac(cipher, cipher.getBlockSize() * 8);
            mac.init(new KeyParameter(keys.getMacKey()));

            return new EBProcessDataCipher(forEncryption, enc, mac);

        } catch (NoSuchAlgorithmException e) {
            throw new EBEngineException(e);
        } catch (NoSuchPaddingException e) {
            throw new EBEngineException(e);
        } catch (InvalidAlgorithmParameterException e) {
            throw new EBEngineException(e);
        } catch (InvalidKeyException e) {
            throw new EBEngineException(e);
        }
    }

    protected void checkValid(){
        if (mac == null || enc == null){
            throw new IllegalStateException("Cipher not initialized");
        }
    }

    /**
     * Gets output buffer size needed for the operation depending on the size of the input.
     * @param inputSize
     * @return
     */
    public int getOutputBufferSize(int inputSize){
        final int cipherBlockSize = enc.getBlockSize();
        int outBuffSize = 0;
        if (forEncryption){
            outBuffSize = inputSize - (inputSize % cipherBlockSize) + cipherBlockSize + macSize;
        } else {
            outBuffSize = inputSize - macSize;
        }

        return outBuffSize;
    }

    /**
     * Performs cipher operation on the given input data.
     * In case of invalid MAC, exception is thrown.
     *
     * @param input
     * @param inputOffset
     * @return
     * @throws EBCryptoException
     */
    public byte[] processBuffer(byte[] input, int inputOffset) throws EBCryptoException {
        checkValid();

        final int inputLen = input.length - inputOffset;
        int outBuffSize = getOutputBufferSize(inputLen);

        byte[] output = new byte[outBuffSize];
        final int processed = processBuffer(input, inputOffset, input.length - inputOffset, output, 0);
        if(processed != outBuffSize){
            byte[] ret = new byte[processed];
            System.arraycopy(output, 0, ret, 0, processed);
            return ret;
        }

        return output;
    }

    /**
     * Performs cipher operation on the given input data.
     * In case of invalid MAC, exception is thrown.
     *
     * @param input
     * @param inputOffset
     * @param inputLength
     * @param output
     * @param outputOffset
     * @return
     */<commit_msg>ProcessData cipher - add2mac method, processBuffer extended - length.<commit_after>package com.enigmabridge.comm;

import com.enigmabridge.EBCommKeys;
import com.enigmabridge.EBCryptoException;
import com.enigmabridge.EBEngineException;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.engines.AESLightEngine;
import org.bouncycastle.crypto.macs.CBCBlockCipherMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Arrays;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * Process data cipher.
 * Encrypt-then-MAC.
 *
 * AES-256/CBC/PKCS7 + HMAC/AES-256/CBC
 *
 * Created by dusanklinec on 26.04.16.
 */
public class EBProcessDataCipher {
    public static final String PROCESS_DATA_CIPHER = "ProcessDataV1";
    public static final byte[] ZERO_IV = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    protected boolean forEncryption;
    protected Cipher enc;
    protected Mac mac;
    protected int macSize;

    public EBProcessDataCipher(boolean forEncryption, Cipher enc, Mac mac) {
        this.forEncryption = forEncryption;
        this.enc = enc;
        this.mac = mac;
        this.macSize = mac.getMacSize();
    }

    /**
     * Creates a new cipher instance with given keys.
     * @param forEncryption
     * @param keys
     * @return
     */
    public static EBProcessDataCipher initCipher(boolean forEncryption, EBCommKeys keys) throws EBEngineException {
        try {
            // Initialize cipher
            final Cipher enc = Cipher.getInstance("AES/CBC/PKCS5Padding");
            enc.init(
                    forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE,
                    new SecretKeySpec(keys.getEncKey(), "AES"),
                    new IvParameterSpec(ZERO_IV));

            // Initialize CBC MAC.
            // There is no AES-CBC-MAC in the BouncyCastle provider.
            final BlockCipher cipher = new AESLightEngine();
            final CBCBlockCipherMac mac = new CBCBlockCipherMac(cipher, cipher.getBlockSize() * 8);
            mac.init(new KeyParameter(keys.getMacKey()));

            return new EBProcessDataCipher(forEncryption, enc, mac);

        } catch (NoSuchAlgorithmException e) {
            throw new EBEngineException(e);
        } catch (NoSuchPaddingException e) {
            throw new EBEngineException(e);
        } catch (InvalidAlgorithmParameterException e) {
            throw new EBEngineException(e);
        } catch (InvalidKeyException e) {
            throw new EBEngineException(e);
        }
    }

    protected void checkValid(){
        if (mac == null || enc == null){
            throw new IllegalStateException("Cipher not initialized");
        }
    }

    /**
     * Gets output buffer size needed for the operation depending on the size of the input.
     * @param inputSize
     * @return
     */
    public int getOutputBufferSize(int inputSize){
        final int cipherBlockSize = enc.getBlockSize();
        int outBuffSize = 0;
        if (forEncryption){
            outBuffSize = inputSize - (inputSize % cipherBlockSize) + cipherBlockSize + macSize;
        } else {
            outBuffSize = inputSize - macSize;
        }

        return outBuffSize;
    }

    /**
     * Used to add data to MAC.
     * @param input
     * @param inputOffset
     * @param length
     */
    public void add2mac(byte[] input, int inputOffset, int length){
        mac.update(input, inputOffset, length);
    }

    /**
     * Performs cipher operation on the given input data.
     * In case of invalid MAC, exception is thrown.
     *
     * @param input
     * @param inputOffset
     * @return
     * @throws EBCryptoException
     */
    public byte[] processBuffer(byte[] input, int inputOffset, int length) throws EBCryptoException {
        checkValid();

        final int inputLen = length - inputOffset;
        int outBuffSize = getOutputBufferSize(inputLen);

        byte[] output = new byte[outBuffSize];
        final int processed = processBuffer(input, inputOffset, length - inputOffset, output, 0);
        if(processed != outBuffSize){
            byte[] ret = new byte[processed];
            System.arraycopy(output, 0, ret, 0, processed);
            return ret;
        }

        return output;
    }

    /**
     * Performs cipher operation on the given input data.
     * In case of invalid MAC, exception is thrown.
     *
     * @param input
     * @param inputOffset
     * @param inputLength
     * @param output
     * @param outputOffset
     * @return
     */
{'fraction_non_alphanumeric': 0.09155967164807409, 'fraction_numerical': 0.007787834140181015, 'mean_word_length': 2.5941754916792736, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3313713', 'n_tokens_mistral': 2799, 'n_tokens_neox': 2654, 'n_words': 695}