Search in sources :

Example 1 with OutputLengthException

use of com.github.zhenwei.core.crypto.OutputLengthException in project LinLong-Java by zhenwei1108.

the class CCMBlockCipher method processPacket.

/**
 * Process a packet of data for either CCM decryption or encryption.
 *
 * @param in     data for processing.
 * @param inOff  offset at which data starts in the input array.
 * @param inLen  length of the data in the input array.
 * @param output output array.
 * @param outOff offset into output array to start putting processed bytes.
 * @return the number of bytes added to output.
 * @throws IllegalStateException      if the cipher is not appropriately set up.
 * @throws InvalidCipherTextException if the input data is truncated or the mac check fails.
 * @throws DataLengthException        if output buffer too short.
 */
public int processPacket(byte[] in, int inOff, int inLen, byte[] output, int outOff) throws IllegalStateException, InvalidCipherTextException, DataLengthException {
    // Need to keep the CTR and CBC Mac parts around and reset
    if (keyParam == null) {
        throw new IllegalStateException("CCM cipher unitialized.");
    }
    int n = nonce.length;
    int q = 15 - n;
    if (q < 4) {
        int limitLen = 1 << (8 * q);
        if (inLen >= limitLen) {
            throw new IllegalStateException("CCM packet too large for choice of q.");
        }
    }
    byte[] iv = new byte[blockSize];
    iv[0] = (byte) ((q - 1) & 0x7);
    System.arraycopy(nonce, 0, iv, 1, nonce.length);
    BlockCipher ctrCipher = new SICBlockCipher(cipher);
    ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
    int outputLen;
    int inIndex = inOff;
    int outIndex = outOff;
    if (forEncryption) {
        outputLen = inLen + macSize;
        if (output.length < (outputLen + outOff)) {
            throw new OutputLengthException("Output buffer too short.");
        }
        calculateMac(in, inOff, inLen, macBlock);
        byte[] encMac = new byte[blockSize];
        // S0
        ctrCipher.processBlock(macBlock, 0, encMac, 0);
        while (// S1...
        inIndex < (inOff + inLen - blockSize)) {
            ctrCipher.processBlock(in, inIndex, output, outIndex);
            outIndex += blockSize;
            inIndex += blockSize;
        }
        byte[] block = new byte[blockSize];
        System.arraycopy(in, inIndex, block, 0, inLen + inOff - inIndex);
        ctrCipher.processBlock(block, 0, block, 0);
        System.arraycopy(block, 0, output, outIndex, inLen + inOff - inIndex);
        System.arraycopy(encMac, 0, output, outOff + inLen, macSize);
    } else {
        if (inLen < macSize) {
            throw new InvalidCipherTextException("data too short");
        }
        outputLen = inLen - macSize;
        if (output.length < (outputLen + outOff)) {
            throw new OutputLengthException("Output buffer too short.");
        }
        System.arraycopy(in, inOff + outputLen, macBlock, 0, macSize);
        ctrCipher.processBlock(macBlock, 0, macBlock, 0);
        for (int i = macSize; i != macBlock.length; i++) {
            macBlock[i] = 0;
        }
        while (inIndex < (inOff + outputLen - blockSize)) {
            ctrCipher.processBlock(in, inIndex, output, outIndex);
            outIndex += blockSize;
            inIndex += blockSize;
        }
        byte[] block = new byte[blockSize];
        System.arraycopy(in, inIndex, block, 0, outputLen - (inIndex - inOff));
        ctrCipher.processBlock(block, 0, block, 0);
        System.arraycopy(block, 0, output, outIndex, outputLen - (inIndex - inOff));
        byte[] calculatedMacBlock = new byte[blockSize];
        calculateMac(output, outOff, outputLen, calculatedMacBlock);
        if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock)) {
            throw new InvalidCipherTextException("mac check in CCM failed");
        }
    }
    return outputLen;
}
Also used : ParametersWithIV(com.github.zhenwei.core.crypto.params.ParametersWithIV) InvalidCipherTextException(com.github.zhenwei.core.crypto.InvalidCipherTextException) BlockCipher(com.github.zhenwei.core.crypto.BlockCipher) OutputLengthException(com.github.zhenwei.core.crypto.OutputLengthException)

Example 2 with OutputLengthException

use of com.github.zhenwei.core.crypto.OutputLengthException in project LinLong-Java by zhenwei1108.

the class CTSBlockCipher method doFinal.

/**
 * Process the last block in the buffer.
 *
 * @param out    the array the block currently being held is copied into.
 * @param outOff the offset at which the copying starts.
 * @return the number of output bytes copied to out.
 * @throws DataLengthException        if there is insufficient space in out for the output.
 * @throws IllegalStateException      if the underlying cipher is not initialised.
 * @throws InvalidCipherTextException if cipher text decrypts wrongly (in case the exception will
 *                                    never get thrown).
 */
public int doFinal(byte[] out, int outOff) throws DataLengthException, IllegalStateException, InvalidCipherTextException {
    if (bufOff + outOff > out.length) {
        throw new OutputLengthException("output buffer to small in doFinal");
    }
    int blockSize = cipher.getBlockSize();
    int len = bufOff - blockSize;
    byte[] block = new byte[blockSize];
    if (forEncryption) {
        if (bufOff < blockSize) {
            throw new DataLengthException("need at least one block of input for CTS");
        }
        cipher.processBlock(buf, 0, block, 0);
        if (bufOff > blockSize) {
            for (int i = bufOff; i != buf.length; i++) {
                buf[i] = block[i - blockSize];
            }
            for (int i = blockSize; i != bufOff; i++) {
                buf[i] ^= block[i - blockSize];
            }
            if (cipher instanceof CBCBlockCipher) {
                BlockCipher c = ((CBCBlockCipher) cipher).getUnderlyingCipher();
                c.processBlock(buf, blockSize, out, outOff);
            } else {
                cipher.processBlock(buf, blockSize, out, outOff);
            }
            System.arraycopy(block, 0, out, outOff + blockSize, len);
        } else {
            System.arraycopy(block, 0, out, outOff, blockSize);
        }
    } else {
        if (bufOff < blockSize) {
            throw new DataLengthException("need at least one block of input for CTS");
        }
        byte[] lastBlock = new byte[blockSize];
        if (bufOff > blockSize) {
            if (cipher instanceof CBCBlockCipher) {
                BlockCipher c = ((CBCBlockCipher) cipher).getUnderlyingCipher();
                c.processBlock(buf, 0, block, 0);
            } else {
                cipher.processBlock(buf, 0, block, 0);
            }
            for (int i = blockSize; i != bufOff; i++) {
                lastBlock[i - blockSize] = (byte) (block[i - blockSize] ^ buf[i]);
            }
            System.arraycopy(buf, blockSize, block, 0, len);
            cipher.processBlock(block, 0, out, outOff);
            System.arraycopy(lastBlock, 0, out, outOff + blockSize, len);
        } else {
            cipher.processBlock(buf, 0, block, 0);
            System.arraycopy(block, 0, out, outOff, blockSize);
        }
    }
    int offset = bufOff;
    reset();
    return offset;
}
Also used : BufferedBlockCipher(com.github.zhenwei.core.crypto.BufferedBlockCipher) BlockCipher(com.github.zhenwei.core.crypto.BlockCipher) StreamBlockCipher(com.github.zhenwei.core.crypto.StreamBlockCipher) DataLengthException(com.github.zhenwei.core.crypto.DataLengthException) OutputLengthException(com.github.zhenwei.core.crypto.OutputLengthException)

Example 3 with OutputLengthException

use of com.github.zhenwei.core.crypto.OutputLengthException in project LinLong-Java by zhenwei1108.

the class ChaCha20Poly1305 method doFinal.

public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException {
    if (null == out) {
        throw new NullPointerException("'out' cannot be null");
    }
    if (outOff < 0) {
        throw new IllegalArgumentException("'outOff' cannot be negative");
    }
    checkData();
    Arrays.clear(mac);
    int resultLen = 0;
    switch(state) {
        case State.DEC_DATA:
            {
                if (bufPos < MAC_SIZE) {
                    throw new InvalidCipherTextException("data too short");
                }
                resultLen = bufPos - MAC_SIZE;
                if (outOff > (out.length - resultLen)) {
                    throw new OutputLengthException("Output buffer too short");
                }
                if (resultLen > 0) {
                    poly1305.update(buf, 0, resultLen);
                    processData(buf, 0, resultLen, out, outOff);
                }
                finishData(State.DEC_FINAL);
                if (!Arrays.constantTimeAreEqual(MAC_SIZE, mac, 0, buf, resultLen)) {
                    throw new InvalidCipherTextException("mac check in ChaCha20Poly1305 failed");
                }
                break;
            }
        case State.ENC_DATA:
            {
                resultLen = bufPos + MAC_SIZE;
                if (outOff > (out.length - resultLen)) {
                    throw new OutputLengthException("Output buffer too short");
                }
                if (bufPos > 0) {
                    processData(buf, 0, bufPos, out, outOff);
                    poly1305.update(out, outOff, bufPos);
                }
                finishData(State.ENC_FINAL);
                System.arraycopy(mac, 0, out, outOff + bufPos, MAC_SIZE);
                break;
            }
        default:
            throw new IllegalStateException();
    }
    reset(false, true);
    return resultLen;
}
Also used : InvalidCipherTextException(com.github.zhenwei.core.crypto.InvalidCipherTextException) OutputLengthException(com.github.zhenwei.core.crypto.OutputLengthException)

Example 4 with OutputLengthException

use of com.github.zhenwei.core.crypto.OutputLengthException in project LinLong-Java by zhenwei1108.

the class GCMBlockCipher method doFinal.

public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException {
    checkStatus();
    if (totalLength == 0) {
        initCipher();
    }
    int extra = bufOff;
    if (forEncryption) {
        if ((out.length - outOff) < (extra + macSize)) {
            throw new OutputLengthException("Output buffer too short");
        }
    } else {
        if (extra < macSize) {
            throw new InvalidCipherTextException("data too short");
        }
        extra -= macSize;
        if ((out.length - outOff) < extra) {
            throw new OutputLengthException("Output buffer too short");
        }
    }
    if (extra > 0) {
        processPartial(bufBlock, 0, extra, out, outOff);
    }
    atLength += atBlockPos;
    if (atLength > atLengthPre) {
        // Finish hash for partial AAD block
        if (atBlockPos > 0) {
            gHASHPartial(S_at, atBlock, 0, atBlockPos);
        }
        // Find the difference between the AAD hashes
        if (atLengthPre > 0) {
            GCMUtil.xor(S_at, S_atPre);
        }
        // Number of cipher-text blocks produced
        long c = ((totalLength * 8) + 127) >>> 7;
        // Calculate the adjustment factor
        byte[] H_c = new byte[16];
        if (exp == null) {
            exp = new BasicGCMExponentiator();
            exp.init(H);
        }
        exp.exponentiateX(c, H_c);
        // Carry the difference forward
        GCMUtil.multiply(S_at, H_c);
        // Adjust the current hash
        GCMUtil.xor(S, S_at);
    }
    // Final gHASH
    byte[] X = new byte[BLOCK_SIZE];
    Pack.longToBigEndian(atLength * 8, X, 0);
    Pack.longToBigEndian(totalLength * 8, X, 8);
    gHASHBlock(S, X);
    // T = MSBt(GCTRk(J0,S))
    byte[] tag = new byte[BLOCK_SIZE];
    cipher.processBlock(J0, 0, tag, 0);
    GCMUtil.xor(tag, S);
    int resultLen = extra;
    // We place into macBlock our calculated value for T
    this.macBlock = new byte[macSize];
    System.arraycopy(tag, 0, macBlock, 0, macSize);
    if (forEncryption) {
        // Append T to the message
        System.arraycopy(macBlock, 0, out, outOff + bufOff, macSize);
        resultLen += macSize;
    } else {
        // Retrieve the T value from the message and compare to calculated one
        byte[] msgMac = new byte[macSize];
        System.arraycopy(bufBlock, extra, msgMac, 0, macSize);
        if (!Arrays.constantTimeAreEqual(this.macBlock, msgMac)) {
            throw new InvalidCipherTextException("mac check in GCM failed");
        }
    }
    reset(false);
    return resultLen;
}
Also used : InvalidCipherTextException(com.github.zhenwei.core.crypto.InvalidCipherTextException) BasicGCMExponentiator(com.github.zhenwei.core.crypto.modes.gcm.BasicGCMExponentiator) OutputLengthException(com.github.zhenwei.core.crypto.OutputLengthException)

Example 5 with OutputLengthException

use of com.github.zhenwei.core.crypto.OutputLengthException in project LinLong-Java by zhenwei1108.

the class GCMSIVBlockCipher method checkBuffer.

/**
 * Check buffer.
 *
 * @param pBuffer the buffer
 * @param pOffset the offset
 * @param pLen    the length
 * @param pOutput is this an output buffer?
 */
private static void checkBuffer(final byte[] pBuffer, final int pOffset, final int pLen, final boolean pOutput) {
    /* Access lengths */
    final int myBufLen = bufLength(pBuffer);
    final int myLast = pOffset + pLen;
    /* Check for negative values and buffer overflow */
    final boolean badLen = pLen < 0 || pOffset < 0 || myLast < 0;
    if (badLen || myLast > myBufLen) {
        throw pOutput ? new OutputLengthException("Output buffer too short.") : new DataLengthException("Input buffer too short.");
    }
}
Also used : DataLengthException(com.github.zhenwei.core.crypto.DataLengthException) OutputLengthException(com.github.zhenwei.core.crypto.OutputLengthException)

Aggregations

OutputLengthException (com.github.zhenwei.core.crypto.OutputLengthException)10 DataLengthException (com.github.zhenwei.core.crypto.DataLengthException)6 BlockCipher (com.github.zhenwei.core.crypto.BlockCipher)4 BufferedBlockCipher (com.github.zhenwei.core.crypto.BufferedBlockCipher)3 InvalidCipherTextException (com.github.zhenwei.core.crypto.InvalidCipherTextException)3 ASN1EncodableVector (com.github.zhenwei.core.asn1.ASN1EncodableVector)1 DEROctetString (com.github.zhenwei.core.asn1.DEROctetString)1 DERSequence (com.github.zhenwei.core.asn1.DERSequence)1 DERTaggedObject (com.github.zhenwei.core.asn1.DERTaggedObject)1 StreamBlockCipher (com.github.zhenwei.core.crypto.StreamBlockCipher)1 BasicGCMExponentiator (com.github.zhenwei.core.crypto.modes.gcm.BasicGCMExponentiator)1 ParametersWithIV (com.github.zhenwei.core.crypto.params.ParametersWithIV)1 IOException (java.io.IOException)1