All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.schlichtherle.truezip.zip.WinZipAesCipher Maven / Gradle / Ivy

Go to download

The file system driver family for ZIP and related archive file types. Add the JAR artifact of this module to the run time class path to make its file system drivers available for service location in the client API modules.

There is a newer version: 7.7.10
Show newest version
/*
 * Copyright (C) 2005-2013 Schlichtherle IT Services.
 * All rights reserved. Use is subject to license terms.
 */
package de.schlichtherle.truezip.zip;

import de.schlichtherle.truezip.crypto.SICSeekableBlockCipher;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.engines.AESFastEngine;

/**
 * Implements Counter (CTR) mode (alias Segmented Integer Counter - SIC)
 * on top of an AES engine.
 * This class is almost identical to {@link SICSeekableBlockCipher} except that
 * the block counter is incremented before updating the cipher input
 * in little endian order.
 *
 * @since   TrueZIP 7.3
 * @see     A Password Based File Encyption Utility (Dr. Gladman)
 * @author  Christian Schlichtherle
 */
final class WinZipAesCipher extends SICSeekableBlockCipher {

    /**
     * Constructs a new block cipher mode for use with WinZip AES.
     * This constructor uses an {@link AESFastEngine} as the underlying block
     * cipher.
     */
    WinZipAesCipher() {
        super(new AESFastEngine());
    }

    @Override
    public int processBlock(
            final byte[] in,
            int inOff,
            final byte[] out,
            int outOff)
    throws DataLengthException, IllegalStateException {
        incCounter();
        this.cipher.processBlock(this.cipherIn, 0, this.cipherOut, 0);

        // XOR the cipherOut with the plaintext producing the cipher text.
        final int blockSize = this.blockSize;
        {
            int i = blockSize;
            inOff += i;
            outOff += i;
            while (i > 0)
                out[--outOff] = (byte) (in[--inOff] ^ this.cipherOut[--i]);
        }

        return blockSize;
    }

    private void incCounter() {
        final int blockSize = this.blockSize;
        long blockCounter = ++this.blockCounter; // pre-increment the block counter!
        for (int i = 0; i < blockSize; i++) { // little endian order!
            blockCounter += IV[i] & 0xff;
            this.cipherIn[i] = (byte) blockCounter;
            blockCounter >>>= 8;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy