Example usage for org.bouncycastle.crypto.modes EAXBlockCipher doFinal

List of usage examples for org.bouncycastle.crypto.modes EAXBlockCipher doFinal

Introduction

In this page you can find the example usage for org.bouncycastle.crypto.modes EAXBlockCipher doFinal.

Prototype

public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException 

Source Link

Usage

From source file:NoekeonVects.java

License:Creative Commons License

public void eax_vectors() throws Exception {
    System.out.println("EAX-noekeon (16 byte key)");
    EAXBlockCipher eax = new EAXBlockCipher(new NoekeonEngine());
    byte[] output = new byte[48];
    byte[] tag = new byte[16];

    for (int j = 0; j < 16; j++)
        tag[j] = (byte) j;

    for (int i = 0; i <= 32; i++) {
        byte[] header_nonce_plaintext = new byte[i];
        for (int j = 0; j < i; j++)
            header_nonce_plaintext[j] = (byte) j;
        AEADParameters params = new AEADParameters(maybe_schedule_key(tag), 128, header_nonce_plaintext,
                header_nonce_plaintext);
        eax.init(true, params);//from  w  w w. ja v  a 2s. c  om
        int off = eax.processBytes(header_nonce_plaintext, 0, i, output, 0);
        off += eax.doFinal(output, off);
        if (off != i + 16)
            throw new RuntimeException("didn't expect that");
        byte[] ciphertext = new byte[i];
        for (int j = 0; j < i; j++)
            ciphertext[j] = output[j];
        for (int j = 0; j < 16; j++)
            tag[j] = output[i + j];
        System.out.print(i < 10 ? "  " : " ");
        System.out.print(i);
        System.out.print(": ");
        hexOut(ciphertext);
        System.out.print(", ");
        hexOut(tag);
        System.out.println();
    }
}

From source file:cologne.eck.peafactory.crypto.EAXMode.java

License:Open Source License

/**
 * Encrypt/decrypt an array of bytes//  w  w w  . j  ava  2  s  .c  o m
 * 
 * @param forEncryption - true for encryption, false for decryption
 * @param input         - plain text or cipher text
 * @param key         - the cryptographic key for the cipher
 * @param nonce         - unique Nonce of 8 byte
 * @return            - plain text or cipher text
 */
public final byte[] processBytes(boolean forEncryption, byte[] input, byte[] key, byte[] nonce) {

    int resultLen = 0;// proceeded bytes

    KeyParameter aeKey = new KeyParameter(key);

    int macLength = CipherStuff.getCipherAlgo().getBlockSize();
    if (macLength < 16) {
        System.out.println("Warning: short mac size: " + macLength);
    }

    EAXBlockCipher eaxCipher = new EAXBlockCipher(CipherStuff.getCipherAlgo());

    AEADParameters params = new AEADParameters(aeKey, macLength * 8, nonce);

    eaxCipher.init(forEncryption, params);

    byte[] result = new byte[eaxCipher.getOutputSize(input.length)];
    resultLen = eaxCipher.processBytes(input, 0, input.length, result, 0);
    try {
        resultLen += eaxCipher.doFinal(result, resultLen);
        // KeyParameter uses a copy of the key: 
        Zeroizer.zero(aeKey.getKey());
    } catch (IllegalStateException e) {
        CipherStuff.setErrorMessage("Internal application error");
        System.err.println("EAXMode - processBytes: " + e.toString());
        return null;
    } catch (InvalidCipherTextException e) {

        System.err.println("Authentication failed. ");
        if (PswDialogBase.getWorkingMode().equals("-r")) { // rescue mode

            Object[] options = { "Continue decryption despite error", "Do not decrypt" };
            int n = JOptionPane.showOptionDialog(null,
                    "Authentication failed:  \n" + "The content is not the previousely encrypted content. \n"
                            + "Normally that means, that the password is not correct, \n"
                            + "but there is the possibility that the file is damaged. \n"
                            + "In this case, some parts of the file might be restored \n"
                            + "by the decryption. \n" + "If you are sure, the password is correct, continue.\n"
                            + "Warning: For incorrect password files may be irretrievably lost. ",
                    "Authentication Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options,
                    options[1]);

            if (n == JOptionPane.YES_OPTION) {
                return result;
            } else {
                return null;
            }
        } else {// not rescue mode
            CipherStuff.setErrorMessage("Authentication failed");
            return null;
        }
    } catch (Exception e) {
        CipherStuff.setErrorMessage("Unexpected error");
        return null;
    }
    return result;
}

From source file:cologne.eck.peafactory.crypto.EAXMode.java

License:Open Source License

/**
 * Encrypt an array of files//from   w w  w .ja  v a2  s.  co  m
 * 
 * @param fileNames    array of file names
 * @param keyMaterial   derived material from KDF, contains the key
 * @param encryptBySessionKey   whether encrypt and store the derived key
 *                         or zeroize it
 * @param filePanel      JPanel to display the progress of encryption
 * @return            array of error messages, with the same indexing as fileNames
 */
public final String[] encryptFiles(String[] fileNames, byte[] keyMaterial, boolean encryptBySessionKey,
        FileTypePanel filePanel) {

    // Attachments: 
    // 1. Padding to plaintext
    // 2. pswIdentifier to ciphertext
    // 3. encryptedPswIdentifier to ciphertext
    // 4. nonce to ciphertext
    // (5. salt to ciphertext if bound == false)
    // 6. fileIdentifier to ciphertext

    //return value: 
    String[] errorMessages = new String[fileNames.length];

    //------------------
    // get the key: 
    //------------------
    byte[] keyBytes = CipherStuff.getInstance().detectKey(keyMaterial);
    KeyParameter key = new KeyParameter(keyBytes);

    int blockSize = CipherStuff.getCipherAlgo().getBlockSize();
    int macSize = blockSize;
    int nonceSize = Attachments.getNonceSize();

    EAXBlockCipher eaxCipher = new EAXBlockCipher(CipherStuff.getCipherAlgo());

    byte[] attachedSalt = null;
    int saltLen = 0;

    if (CipherStuff.isBound() == false) {

        if (KeyDerivation.getAttachedSalt() == null) {

            KeyDerivation.setSalt(Attachments.getProgramRandomBytes());
            attachedSalt = new RandomStuff().createRandomBytes(KeyDerivation.getSaltSize());
            // this will set attachedSalt and update the salt:
            KeyDerivation.setAttachedAndUpdateSalt(attachedSalt);
        }
        saltLen = KeyDerivation.getSaltSize();
    }

    //----------------------------------
    // encrypt the files:  
    // attach pswIdenitfier, do padding, 
    // encrypt block by block, 
    // attach IV, attach salt (if bound == false),
    // attach fileIdentifier
    //----------------------------------
    int progress = 0;

    for (int i = 0; i < fileNames.length; i++) {

        RandomAccessFile f = null;

        try {
            // update progress for each file (don't care about file length)
            filePanel.setProgressValue(progress);
            progress += 1000 / fileNames.length;

            if (new File(fileNames[i]).isDirectory()) {
                continue;
            }
            f = new RandomAccessFile(fileNames[i], "rwd");

            long fileSizeLong = f.length();
            if (fileSizeLong > (Integer.MAX_VALUE - (nonceSize * 2) // for pswIdentifier
                    - blockSize // mac 
                    - saltLen // o if bounded
                    - Attachments.getNonceSize())) {// Nonce
                errorMessages[i] = "file too large";
                continue;
            }
            int fileSize = (int) fileSizeLong;

            // random Nonce for each file
            byte[] nonce = Attachments.generateNonce();

            byte[] block = new byte[FILE_BLOCK_SIZE];

            // generate random pswIdentifier of 8 bytes:
            byte[] pswIdentifier = Attachments.generateNonce(); // 8 byte            

            AEADParameters idParams = new AEADParameters(key, 0, nonce, null);// no mac             
            eaxCipher.init(true, idParams);
            byte[] encryptedPswIdentifier = new byte[eaxCipher.getOutputSize(nonceSize)];

            // encrypt pswIdentifier without mac and store in 
            int processedIDBytes = eaxCipher.processBytes(pswIdentifier, 0, nonceSize, encryptedPswIdentifier,
                    nonceSize);
            eaxCipher.doFinal(encryptedPswIdentifier, processedIDBytes);
            eaxCipher.reset();

            fileSize = (int) f.length();
            // round down: get block number except last block
            int blockNumber = (fileSize / FILE_BLOCK_SIZE);
            if (fileSize % FILE_BLOCK_SIZE == 0) {
                blockNumber--;
            }

            if (macSize < 16) {
                System.out.println("Warning: short mac size: " + macSize);
            }
            AEADParameters params = new AEADParameters(key, macSize * 8, nonce, null);//associatedText);

            eaxCipher.init(true, params);

            int processedBytes = 0;

            // process the blocks:
            for (int j = 0; j < blockNumber; j++) { // only full blocks

                f.seek(j * FILE_BLOCK_SIZE);
                f.read(block, 0, FILE_BLOCK_SIZE);

                byte[] out = new byte[FILE_BLOCK_SIZE];

                processedBytes += eaxCipher.processBytes(block, 0, FILE_BLOCK_SIZE, out, 0);

                f.seek(j * FILE_BLOCK_SIZE);
                f.write(out, 0, FILE_BLOCK_SIZE);
            }

            // process the last (maybe only) block:
            f.seek(FILE_BLOCK_SIZE * blockNumber);
            int lastSize = fileSize - (FILE_BLOCK_SIZE * blockNumber);

            byte[] lastBlock = new byte[lastSize];

            f.read(lastBlock, 0, lastBlock.length);

            byte[] lastOut = new byte[eaxCipher.getOutputSize(lastSize)];

            processedBytes = 0;

            processedBytes += eaxCipher.processBytes(lastBlock, 0, lastSize, lastOut, 0);
            Zeroizer.zero(lastBlock);
            processedBytes += eaxCipher.doFinal(lastOut, processedBytes); // + extra + macSize

            f.seek(FILE_BLOCK_SIZE * blockNumber);
            f.write(lastOut, 0, lastOut.length);

            // add pswIdentifier to ciphertext file: 
            f.seek(f.length()); // set file pointer to end
            f.write(pswIdentifier, 0, pswIdentifier.length);
            f.seek(f.length());
            // add encryptedPswIdentifier to ciphertext file
            f.write(encryptedPswIdentifier, 0, encryptedPswIdentifier.length);

            // add nonce to ciphertext file
            Attachments.addNonce(f, nonce);

            if (CipherStuff.isBound() == false) {

                // if not bound: add salt to ciphertext file
                Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
            }

            // add fileIdetifier to check later if this file was encrypted with this archive
            Attachments.addFileIdentifier(f);

            f.close();

        } catch (FileNotFoundException e) {
            errorMessages[i] = "file not found";
            System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
            try {
                f.close();

            } catch (IOException e1) {
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                try {
                    eaxCipher.reset();
                } catch (Exception e2) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;
            } catch (NullPointerException npe) {
                errorMessages[i] += " - file is probably used by other program";
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                try {
                    eaxCipher.reset();
                } catch (Exception e1) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;
            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();
        } catch (IOException e) {
            errorMessages[i] = "read/write failed";
            System.err.println("CryptStuff " + e.toString() + ", file: " + fileNames[i]);
            try {
                f.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                eaxCipher.reset();
                continue;
            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();
        } catch (Exception e) {
            errorMessages[i] = "unexpected error: " + e.getMessage();
            System.err.println("CryptStuff " + e.toString() + ", file: " + fileNames[i]);
            e.printStackTrace();
            try {
                f.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                eaxCipher.reset();
                continue;
            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();         
        }
        eaxCipher.reset();
    } // end for      

    //-----------------
    // Handle the keys:
    // encrypt or fill
    //-----------------
    CipherStuff.getInstance().handleKey(key.getKey(), encryptBySessionKey);

    return errorMessages;
}

From source file:cologne.eck.peafactory.crypto.EAXMode.java

License:Open Source License

/**
 * Decrypt an array of files//from   w ww .  j av a 2  s. co m
 * 
 * @param fileNames    array of file names
 * @param keyMaterial   derived material from KDF, contains the key
 * @param encryptBySessionKey   whether encrypt and store the derived key
 *                         or zeroize it
 * @param filePanel      JPanel to display the progress of encryption
 * @return            array of error messages, with the same indexing as fileNames
 */
public final String[] decryptFiles(String[] fileNames, byte[] keyMaterial, boolean encryptBySessionKey,
        FileTypePanel filePanel) {

    int fileNamesLen = fileNames.length;

    //return value: 
    String[] errorMessages = new String[fileNamesLen];

    // Attachments: 
    // 1. cut fileIdentifier from ciphertext
    // (2. cut salt from Ciphertext if bound == false)
    // 3. cut nonce from ciphertext
    // 4. cut encryptedPswIdentifier from ciphertext
    // 5. cut pswIdentifier from ciphertext
    // 6. undo padding

    //------------------
    // get the key: 
    //------------------
    byte[] keyBytes = CipherStuff.getInstance().detectKey(keyMaterial);
    KeyParameter key = new KeyParameter(keyBytes);

    int blockSize = CipherStuff.getCipherAlgo().getBlockSize();
    int macSize = blockSize;
    int nonceSize = Attachments.getNonceSize();

    int blockNumber = 0;

    EAXBlockCipher eaxCipher = new EAXBlockCipher(CipherStuff.getCipherAlgo());

    //----------------------------------
    // decrypt the files: 
    // decrypt block by block, 
    // add short plain text and cipher text to check password
    // attach Nonce, attach fileIdentifier
    //----------------------------------
    int progress = 0;

    int saltLen = 0;
    if (CipherStuff.isBound() == false) {
        saltLen = KeyDerivation.getSaltSize();
    }

    for (int i = 0; i < fileNamesLen; i++) {

        RandomAccessFile f = null;
        byte[] lastNonce = null;// to add if error occurs
        int blockCounter = 0;// to get block where authentication failed

        try {

            // update progress for each file (don't care about file length)
            filePanel.setProgressValue(progress);
            progress += 1000 / fileNamesLen;

            if (new File(fileNames[i]).isDirectory()) {
                continue;
            }
            f = new RandomAccessFile(fileNames[i], "rwd");

            int fileSize = (int) f.length();
            if (fileSize < (macSize + (nonceSize * 3) // Nonce + pswId + encPswId  
                    + saltLen // 0 if bounded
                    + Attachments.getFileIdentifierSize())) {
                errorMessages[i] = "inappropriate file (length)";
                System.err.println("file size < minimum: " + fileNames[i]);
                f.close();
                continue;
            }
            // cut fileIdentifier
            if (Attachments.checkFileIdentifier(f, true) == false) { // truncates if true
                errorMessages[i] = "inappropriate file (identifier)";
                System.err.println("file identifier failed: " + fileNames[i]);
                f.close();
                continue;
            }
            // cut the salt
            if (CipherStuff.isBound() == false) {

                byte[] attachedSalt = Attachments.getAndCutSalt(f, true);

                if (Comparator.compare(attachedSalt, KeyDerivation.getAttachedSalt()) == false) {

                    errorMessages[i] = "salt differs from first selected file";
                    System.err.println("different salt: " + fileNames[i]);
                    f.close();
                    if (i == fileNamesLen - 1) {
                        return errorMessages;
                    } else {
                        continue;
                    }
                }
            }
            // get and cut random Nonce for each file
            byte[] nonce = Attachments.getAndCutNonce(f, true);
            lastNonce = nonce;

            // Check and cut pswIdentifier:
            f.seek(f.length() - (nonceSize * 2));// 
            byte[] bytesToCheckPswIdentifier = new byte[nonceSize * 2];
            f.read(bytesToCheckPswIdentifier);
            byte[] pswIdentifier = new byte[nonceSize];
            byte[] encryptedPswIdentifier = new byte[nonceSize];
            System.arraycopy(bytesToCheckPswIdentifier, 0, pswIdentifier, 0, nonceSize);
            System.arraycopy(bytesToCheckPswIdentifier, nonceSize, encryptedPswIdentifier, 0, nonceSize);

            AEADParameters idParams = new AEADParameters(key, 0, nonce, null);// no mac             
            eaxCipher.init(false, idParams);
            byte[] decryptedPswIdentifier = new byte[eaxCipher.getOutputSize(nonceSize)];

            int procesedIDBytes = eaxCipher.processBytes(encryptedPswIdentifier, 0, nonceSize,
                    decryptedPswIdentifier, nonceSize);
            eaxCipher.doFinal(decryptedPswIdentifier, procesedIDBytes);

            // compare:
            boolean check = Comparator.compare(pswIdentifier, decryptedPswIdentifier);

            if (check == false) {
                errorMessages[i] = "password failed";
                System.out.println("password failed: identifier not equal");
                try {
                    Attachments.addNonce(f, nonce);
                    if (CipherStuff.isBound() == false) {
                        Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
                    }
                    Attachments.addFileIdentifier(f);
                    f.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                eaxCipher.reset();
                continue;
            } else {
                f.setLength(f.length() - (nonceSize * 2));
            }
            eaxCipher.reset();

            byte[] block = new byte[FILE_BLOCK_SIZE];
            fileSize = (int) f.length();
            // round down: get block number except last block
            blockNumber = ((fileSize - macSize) / FILE_BLOCK_SIZE);
            if ((fileSize - macSize) % FILE_BLOCK_SIZE == 0) {
                blockNumber--;
            }

            //   byte[] associatedText = Attachments.getFileIdentifier();// 8 byte, not really necessary
            AEADParameters params = new AEADParameters(key, macSize * 8, nonce, null);//associatedText);

            eaxCipher.init(false, params);

            int processedBytes = 0;

            // process the blocks:
            for (blockCounter = 0; blockCounter < blockNumber; blockCounter++) { // only full blocks

                f.seek(blockCounter * FILE_BLOCK_SIZE);
                f.read(block, 0, FILE_BLOCK_SIZE);

                byte[] out = new byte[FILE_BLOCK_SIZE];
                processedBytes += eaxCipher.processBytes(block, 0, FILE_BLOCK_SIZE, out, 0);

                f.seek(blockCounter * FILE_BLOCK_SIZE);
                f.write(out, 0, FILE_BLOCK_SIZE);
            }

            // process the last (maybe only) block:
            f.seek(FILE_BLOCK_SIZE * blockNumber);

            byte[] lastBlock = new byte[fileSize - (FILE_BLOCK_SIZE * blockNumber)];
            f.read(lastBlock, 0, lastBlock.length);

            byte[] lastOut = new byte[eaxCipher.getOutputSize(lastBlock.length)];
            processedBytes = 0; // reset            
            processedBytes += eaxCipher.processBytes(lastBlock, 0, lastBlock.length, lastOut, 0);
            processedBytes += eaxCipher.doFinal(lastOut, processedBytes); // + macSize

            f.seek(FILE_BLOCK_SIZE * blockNumber);
            f.write(lastOut, 0, lastOut.length);

            // truncate file (mac and extra bytes):
            f.setLength(FILE_BLOCK_SIZE * blockNumber + lastOut.length);

            f.close();

        } catch (FileNotFoundException e) {
            errorMessages[i] = "file not found";
            System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
            try {
                Attachments.addNonce(f, lastNonce);
                Attachments.addFileIdentifier(f);
                f.close();
            } catch (IOException e1) {
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                try {
                    eaxCipher.reset();
                } catch (Exception e2) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;

            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();
        } catch (IOException e) {
            errorMessages[i] = "read/write failed";
            System.err
                    .println("CryptStuff " + e.toString() + ": " + e.getMessage() + ", file: " + fileNames[i]);
            try {
                Attachments.addNonce(f, lastNonce);
                Attachments.addFileIdentifier(f);
                f.close();
            } catch (IOException e1) {
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                try {
                    eaxCipher.reset();
                } catch (Exception e2) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;
            }
            eaxCipher.reset();
            continue;
            //e.printStackTrace();
        } catch (InvalidCipherTextException icte) {// Authentication failed

            if (PswDialogBase.getWorkingMode().equals("-r")) { // rescue mode: 
                System.out.println("===============   Corrupted file   =====================");
                System.out.println("Authentication failed, block: " + blockCounter + "  file: " + fileNames[i]);
                System.out.println("========================================================\n");
            } else {// try to undo decryption:
                JOptionPane.showMessageDialog(PswDialogView.getView(),
                        "The file \n" + fileNames[i] + "\n has been corrupted at block " + blockCounter
                                + ".\n\n"
                                + "The reason may be a simple error of the medium or a targeted manipulation.\n"
                                + "The Decryption of the file is cancelled. \n"
                                + "The program will now try to restore the original state.\n"
                                + "You can run this pea in rescue mode to decrypt this file anyway:\n "
                                + "java -jar " + PeaSettings.getJarFileName() + ".jar -r",
                        "Authentication failed", JOptionPane.ERROR_MESSAGE);
                errorMessages[i] = "authentication failed - encrypted file was corrupted";
                System.err.println("CryptStuff " + icte.toString() + ", file: " + fileNames[i]);
                System.err.println(
                        "You can try to run in rescue modus (Parameter -r)\n java -jar THIS_PEA.jar -r");
                System.out.println("===============   Corrupted file   =====================");
                System.out.println(
                        "You can try to run in rescue modus (Parameter -r)\n java -jar THIS_PEA.jar -r");
                System.out.println("========================================================");
                //icte.printStackTrace();
                try {
                    if (blockNumber == 0) { // only last block, nothing was written
                        Attachments.addNonce(f, lastNonce);
                        if (CipherStuff.isBound() == false) {
                            Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
                        }
                        Attachments.addFileIdentifier(f);
                        f.close();
                    } else {
                        System.out.println("Try to undo decryption...");
                        // encrypt blocks
                        AEADParameters params = new AEADParameters(key, macSize * 8, lastNonce, null);//associatedText);                
                        eaxCipher.init(true, params);
                        // process the blocks:
                        byte[] repairBlock = new byte[FILE_BLOCK_SIZE];
                        for (int j = 0; j < blockCounter; j++) { // only full blocks
                            f.seek(j * FILE_BLOCK_SIZE);
                            f.read(repairBlock, 0, FILE_BLOCK_SIZE);
                            byte[] out = new byte[FILE_BLOCK_SIZE];
                            eaxCipher.processBytes(repairBlock, 0, FILE_BLOCK_SIZE, out, 0);
                            f.seek(j * FILE_BLOCK_SIZE);
                            f.write(out, 0, FILE_BLOCK_SIZE);
                        }
                        // generate pswIdentifier:
                        byte[] pswId = Attachments.generateNonce(); // 8 byte             
                        AEADParameters idParams = new AEADParameters(key, 0, lastNonce, null);// no mac             
                        eaxCipher.init(true, idParams);
                        byte[] idOut = new byte[eaxCipher.getOutputSize(pswId.length)];
                        int procesedIDBytes = eaxCipher.processBytes(pswId, 0, pswId.length, idOut,
                                pswId.length);
                        eaxCipher.doFinal(idOut, procesedIDBytes);
                        eaxCipher.reset();
                        // ad pswIdentifier: 
                        f.seek(f.length()); // set file pointer to end
                        f.write(pswId, 0, pswId.length);
                        f.seek(f.length());
                        f.write(idOut, 0, idOut.length);

                        Attachments.addNonce(f, lastNonce);
                        if (CipherStuff.isBound() == false) {
                            Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
                        }
                        Attachments.addFileIdentifier(f);

                        f.close();
                        eaxCipher.reset();
                        continue;
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    errorMessages[i] += " - " + e.toString();
                    System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                    try {
                        eaxCipher.reset();
                    } catch (Exception e1) {
                        System.err.println("EAXMode: Cipher reset failed");
                    }
                    continue;
                }
                try {
                    eaxCipher.reset();
                } catch (Exception e1) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;
                //e.printStackTrace();
            }
        } catch (Exception e) {
            errorMessages[i] = "unexpected error: " + e.getMessage();
            System.err
                    .println("CryptStuff " + e.toString() + ": " + e.getMessage() + ", file: " + fileNames[i]);
            try {
                Attachments.addNonce(f, lastNonce);
                if (CipherStuff.isBound() == false) {
                    Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
                }
                Attachments.addFileIdentifier(f);
                f.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();         
        }
        eaxCipher.reset();
    } // end for      

    //---------------
    // Handle keys:
    // encrypt or fill
    //----------------
    CipherStuff.getInstance().handleKey(key.getKey(), encryptBySessionKey);

    return errorMessages;
}