Search in sources :

Example 1 with BlockCipher

use of org.bouncycastle.crypto.BlockCipher in project robovm by robovm.

the class CCMBlockCipher method processPacket.

public byte[] processPacket(byte[] in, int inOff, int inLen) throws IllegalStateException, InvalidCipherTextException {
    // 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 index = inOff;
    int outOff = 0;
    byte[] output;
    if (forEncryption) {
        output = new byte[inLen + macSize];
        calculateMac(in, inOff, inLen, macBlock);
        // S0
        ctrCipher.processBlock(macBlock, 0, macBlock, 0);
        while (// S1...
        index < inLen - blockSize) {
            ctrCipher.processBlock(in, index, output, outOff);
            outOff += blockSize;
            index += blockSize;
        }
        byte[] block = new byte[blockSize];
        System.arraycopy(in, index, block, 0, inLen - index);
        ctrCipher.processBlock(block, 0, block, 0);
        System.arraycopy(block, 0, output, outOff, inLen - index);
        outOff += inLen - index;
        System.arraycopy(macBlock, 0, output, outOff, output.length - outOff);
    } else {
        output = new byte[inLen - macSize];
        System.arraycopy(in, inOff + inLen - macSize, macBlock, 0, macSize);
        ctrCipher.processBlock(macBlock, 0, macBlock, 0);
        for (int i = macSize; i != macBlock.length; i++) {
            macBlock[i] = 0;
        }
        while (outOff < output.length - blockSize) {
            ctrCipher.processBlock(in, index, output, outOff);
            outOff += blockSize;
            index += blockSize;
        }
        byte[] block = new byte[blockSize];
        System.arraycopy(in, index, block, 0, output.length - outOff);
        ctrCipher.processBlock(block, 0, block, 0);
        System.arraycopy(block, 0, output, outOff, output.length - outOff);
        byte[] calculatedMacBlock = new byte[blockSize];
        calculateMac(output, 0, output.length, calculatedMacBlock);
        if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock)) {
            throw new InvalidCipherTextException("mac check in CCM failed");
        }
    }
    return output;
}
Also used : ParametersWithIV(org.bouncycastle.crypto.params.ParametersWithIV) InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) BlockCipher(org.bouncycastle.crypto.BlockCipher)

Example 2 with BlockCipher

use of org.bouncycastle.crypto.BlockCipher in project XobotOS by xamarin.

the class CCMBlockCipher method processPacket.

public byte[] processPacket(byte[] in, int inOff, int inLen) throws IllegalStateException, InvalidCipherTextException {
    if (keyParam == null) {
        throw new IllegalStateException("CCM cipher unitialized.");
    }
    BlockCipher ctrCipher = new SICBlockCipher(cipher);
    byte[] iv = new byte[blockSize];
    byte[] out;
    iv[0] = (byte) (((15 - nonce.length) - 1) & 0x7);
    System.arraycopy(nonce, 0, iv, 1, nonce.length);
    ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
    if (forEncryption) {
        int index = inOff;
        int outOff = 0;
        out = new byte[inLen + macSize];
        calculateMac(in, inOff, inLen, macBlock);
        // S0
        ctrCipher.processBlock(macBlock, 0, macBlock, 0);
        while (// S1...
        index < inLen - blockSize) {
            ctrCipher.processBlock(in, index, out, outOff);
            outOff += blockSize;
            index += blockSize;
        }
        byte[] block = new byte[blockSize];
        System.arraycopy(in, index, block, 0, inLen - index);
        ctrCipher.processBlock(block, 0, block, 0);
        System.arraycopy(block, 0, out, outOff, inLen - index);
        outOff += inLen - index;
        System.arraycopy(macBlock, 0, out, outOff, out.length - outOff);
    } else {
        int index = inOff;
        int outOff = 0;
        out = new byte[inLen - macSize];
        System.arraycopy(in, inOff + inLen - macSize, macBlock, 0, macSize);
        ctrCipher.processBlock(macBlock, 0, macBlock, 0);
        for (int i = macSize; i != macBlock.length; i++) {
            macBlock[i] = 0;
        }
        while (outOff < out.length - blockSize) {
            ctrCipher.processBlock(in, index, out, outOff);
            outOff += blockSize;
            index += blockSize;
        }
        byte[] block = new byte[blockSize];
        System.arraycopy(in, index, block, 0, out.length - outOff);
        ctrCipher.processBlock(block, 0, block, 0);
        System.arraycopy(block, 0, out, outOff, out.length - outOff);
        byte[] calculatedMacBlock = new byte[blockSize];
        calculateMac(out, 0, out.length, calculatedMacBlock);
        if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock)) {
            throw new InvalidCipherTextException("mac check in CCM failed");
        }
    }
    return out;
}
Also used : ParametersWithIV(org.bouncycastle.crypto.params.ParametersWithIV) InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) BlockCipher(org.bouncycastle.crypto.BlockCipher)

Example 3 with BlockCipher

use of org.bouncycastle.crypto.BlockCipher in project oxAuth by GluuFederation.

the class JweDecrypterImpl method decryptCipherText.

@Override
public String decryptCipherText(String encodedCipherText, byte[] contentMasterKey, byte[] initializationVector, byte[] authenticationTag, byte[] additionalAuthenticatedData) throws InvalidJweException {
    if (getBlockEncryptionAlgorithm() == null) {
        throw new InvalidJweException("The block encryption algorithm is null");
    }
    if (contentMasterKey == null) {
        throw new InvalidJweException("The content master key (CMK) is null");
    }
    if (initializationVector == null) {
        throw new InvalidJweException("The initialization vector is null");
    }
    if (authenticationTag == null) {
        throw new InvalidJweException("The authentication tag is null");
    }
    if (additionalAuthenticatedData == null) {
        throw new InvalidJweException("The additional authentication data is null");
    }
    try {
        if (getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A128GCM || getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A256GCM) {
            final int MAC_SIZE_BITS = 128;
            byte[] cipherText = Base64Util.base64urldecode(encodedCipherText);
            KeyParameter key = new KeyParameter(contentMasterKey);
            AEADParameters aeadParameters = new AEADParameters(key, MAC_SIZE_BITS, initializationVector, additionalAuthenticatedData);
            SecretKeySpec sks = new SecretKeySpec(contentMasterKey, "AES");
            BlockCipher blockCipher = new AESEngine();
            CipherParameters params = new KeyParameter(sks.getEncoded());
            blockCipher.init(false, params);
            GCMBlockCipher aGCMBlockCipher = new GCMBlockCipher(blockCipher);
            aGCMBlockCipher.init(false, aeadParameters);
            byte[] input = new byte[cipherText.length + authenticationTag.length];
            System.arraycopy(cipherText, 0, input, 0, cipherText.length);
            System.arraycopy(authenticationTag, 0, input, cipherText.length, authenticationTag.length);
            int len = aGCMBlockCipher.getOutputSize(input.length);
            byte[] out = new byte[len];
            int outOff = aGCMBlockCipher.processBytes(input, 0, input.length, out, 0);
            aGCMBlockCipher.doFinal(out, outOff);
            String plaintext = new String(out, Charset.forName(Util.UTF8_STRING_ENCODING));
            return plaintext;
        } else if (getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A128CBC_PLUS_HS256 || getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A256CBC_PLUS_HS512) {
            byte[] cipherText = Base64Util.base64urldecode(encodedCipherText);
            byte[] cek = KeyDerivationFunction.generateCek(contentMasterKey, getBlockEncryptionAlgorithm());
            Cipher cipher = Cipher.getInstance(getBlockEncryptionAlgorithm().getAlgorithm());
            IvParameterSpec ivParameter = new IvParameterSpec(initializationVector);
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(cek, "AES"), ivParameter);
            byte[] decodedPlainTextBytes = cipher.doFinal(cipherText);
            String decodedPlainText = new String(decodedPlainTextBytes, Charset.forName(Util.UTF8_STRING_ENCODING));
            // Integrity check
            String securedInputValue = new String(additionalAuthenticatedData, Charset.forName(Util.UTF8_STRING_ENCODING)) + "." + encodedCipherText;
            byte[] cik = KeyDerivationFunction.generateCik(contentMasterKey, getBlockEncryptionAlgorithm());
            SecretKey secretKey = new SecretKeySpec(cik, getBlockEncryptionAlgorithm().getIntegrityValueAlgorithm());
            Mac mac = Mac.getInstance(getBlockEncryptionAlgorithm().getIntegrityValueAlgorithm());
            mac.init(secretKey);
            byte[] integrityValue = mac.doFinal(securedInputValue.getBytes(Util.UTF8_STRING_ENCODING));
            if (!Arrays.equals(integrityValue, authenticationTag)) {
                throw new InvalidJweException("The authentication tag is not valid");
            }
            return decodedPlainText;
        } else {
            throw new InvalidJweException("The block encryption algorithm is not supported");
        }
    } catch (InvalidCipherTextException e) {
        throw new InvalidJweException(e);
    } catch (NoSuchPaddingException e) {
        throw new InvalidJweException(e);
    } catch (BadPaddingException e) {
        throw new InvalidJweException(e);
    } catch (InvalidAlgorithmParameterException e) {
        throw new InvalidJweException(e);
    } catch (NoSuchAlgorithmException e) {
        throw new InvalidJweException(e);
    } catch (IllegalBlockSizeException e) {
        throw new InvalidJweException(e);
    } catch (UnsupportedEncodingException e) {
        throw new InvalidJweException(e);
    } catch (NoSuchProviderException e) {
        throw new InvalidJweException(e);
    } catch (InvalidKeyException e) {
        throw new InvalidJweException(e);
    } catch (InvalidParameterException e) {
        throw new InvalidJweException(e);
    }
}
Also used : InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) InvalidParameterException(org.xdi.oxauth.model.exception.InvalidParameterException) SecretKeySpec(javax.crypto.spec.SecretKeySpec) InvalidJweException(org.xdi.oxauth.model.exception.InvalidJweException) AESEngine(org.bouncycastle.crypto.engines.AESEngine) BlockCipher(org.bouncycastle.crypto.BlockCipher) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher) UnsupportedEncodingException(java.io.UnsupportedEncodingException) CipherParameters(org.bouncycastle.crypto.CipherParameters) AEADParameters(org.bouncycastle.crypto.params.AEADParameters) IvParameterSpec(javax.crypto.spec.IvParameterSpec) BlockCipher(org.bouncycastle.crypto.BlockCipher) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher)

Example 4 with BlockCipher

use of org.bouncycastle.crypto.BlockCipher in project robovm by robovm.

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.
     * @exception DataLengthException if there is insufficient space in out for
     * the output.
     * @exception IllegalStateException if the underlying cipher is not
     * initialised.
     * @exception 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 DataLengthException("output buffer to small in doFinal");
    }
    int blockSize = cipher.getBlockSize();
    int len = bufOff - blockSize;
    byte[] block = new byte[blockSize];
    if (forEncryption) {
        cipher.processBlock(buf, 0, block, 0);
        if (bufOff < blockSize) {
            throw new DataLengthException("need at least one block of input for CTS");
        }
        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 {
        byte[] lastBlock = new byte[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);
    }
    int offset = bufOff;
    reset();
    return offset;
}
Also used : BufferedBlockCipher(org.bouncycastle.crypto.BufferedBlockCipher) BlockCipher(org.bouncycastle.crypto.BlockCipher) DataLengthException(org.bouncycastle.crypto.DataLengthException)

Example 5 with BlockCipher

use of org.bouncycastle.crypto.BlockCipher in project XobotOS by xamarin.

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.
     * @exception DataLengthException if there is insufficient space in out for
     * the output.
     * @exception IllegalStateException if the underlying cipher is not
     * initialised.
     * @exception 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 DataLengthException("output buffer to small in doFinal");
    }
    int blockSize = cipher.getBlockSize();
    int len = bufOff - blockSize;
    byte[] block = new byte[blockSize];
    if (forEncryption) {
        cipher.processBlock(buf, 0, block, 0);
        if (bufOff < blockSize) {
            throw new DataLengthException("need at least one block of input for CTS");
        }
        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 {
        byte[] lastBlock = new byte[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);
    }
    int offset = bufOff;
    reset();
    return offset;
}
Also used : BufferedBlockCipher(org.bouncycastle.crypto.BufferedBlockCipher) BlockCipher(org.bouncycastle.crypto.BlockCipher) DataLengthException(org.bouncycastle.crypto.DataLengthException)

Aggregations

BlockCipher (org.bouncycastle.crypto.BlockCipher)6 InvalidCipherTextException (org.bouncycastle.crypto.InvalidCipherTextException)4 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 IvParameterSpec (javax.crypto.spec.IvParameterSpec)2 SecretKeySpec (javax.crypto.spec.SecretKeySpec)2 BufferedBlockCipher (org.bouncycastle.crypto.BufferedBlockCipher)2 CipherParameters (org.bouncycastle.crypto.CipherParameters)2 DataLengthException (org.bouncycastle.crypto.DataLengthException)2 AESEngine (org.bouncycastle.crypto.engines.AESEngine)2 GCMBlockCipher (org.bouncycastle.crypto.modes.GCMBlockCipher)2 AEADParameters (org.bouncycastle.crypto.params.AEADParameters)2 KeyParameter (org.bouncycastle.crypto.params.KeyParameter)2 ParametersWithIV (org.bouncycastle.crypto.params.ParametersWithIV)2 InvalidJweException (org.xdi.oxauth.model.exception.InvalidJweException)2 InvalidParameterException (org.xdi.oxauth.model.exception.InvalidParameterException)2 Pair (org.xdi.oxauth.model.util.Pair)1