Пример #1
0
        /// <summary>
        ///     Initialises a block cipher from cipher configuration DTO. Used by constructor.
        /// </summary>
        private static ICipherWrapper InitBlockCipher(bool encrypting, CipherConfiguration config, byte[] key, out int maxDelta)
        {
            var blockConfigWrapper = new BlockCipherConfigurationWrapper(config);

            if (key.Length != blockConfigWrapper.KeySizeBytes)
            {
                throw new ArgumentException("Key is not of the length declared in the cipher configuration.",
                                            "key");
            }

            BlockCipherBase blockCipherPrimitive = CipherFactory.CreateBlockCipher(blockConfigWrapper.GetBlockCipher(),
                                                                                   blockConfigWrapper.GetBlockSizeBits());
            // Overlay the cipher with the mode of operation
            BlockCipherModeBase blockCipher;

            try {
                blockCipher = CipherFactory.OverlayBlockCipherWithMode(blockCipherPrimitive, blockConfigWrapper.Mode);
            } catch (Exception e) {
                throw new ConfigurationInvalidException(
                          "Configuration of block cipher mode of operation is invalid.", e.InnerException);
            }
            IBlockCipherPadding padding     = null;
            BlockCipherPadding  paddingEnum = blockConfigWrapper.GetPadding();

            if (paddingEnum != BlockCipherPadding.None)
            {
                padding = CipherFactory.CreatePadding(paddingEnum);
                padding.Init(StratCom.EntropySupplier);
            }

            maxDelta = Athena.Cryptography.BlockCiphers[blockCipherPrimitive.Identity].MaximumOutputSizeDifference(encrypting);

            blockCipher.Init(encrypting, key, blockConfigWrapper.GetInitialisationVector());
            return(new BlockCipherWrapper(encrypting, blockCipher, padding));
        }
Пример #2
0
        /**
         * Create a buffered block cipher with the desired padding.
         *
         * @param cipher the underlying block cipher this buffering object wraps.
         * @param padding the padding type.
         */
        public PaddedBufferedBlockCipher(
            BlockCipher cipher,
            BlockCipherPadding padding)
        {
            this.cipher  = cipher;
            this.padding = padding;

            buf    = new byte[cipher.getBlockSize()];
            bufOff = 0;
        }
Пример #3
0
        /**
         * create a standard MAC based on a block cipher with the size of the
         * MAC been given in bits. This class uses CBC mode as the basis for the
         * MAC generation.
         * <p>
         * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81),
         * or 16 bits if being used as a data authenticator (FIPS Publication 113),
         * and in general should be less than the size of the block cipher as it reduces
         * the chance of an exhaustive attack (see Handbook of Applied Cryptography).
         *
         * @param cipher the cipher to be used as the basis of the MAC generation.
         * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8.
         * @param padding the padding to be used to complete the last block.
         */
        public CBCBlockCipherMac(
            BlockCipher cipher,
            int macSizeInBits,
            BlockCipherPadding padding)
        {
            if ((macSizeInBits % 8) != 0)
            {
                throw new ArgumentException("MAC size must be multiple of 8");
            }

            this.cipher  = new CBCBlockCipher(cipher);
            this.padding = padding;
            this.macSize = macSizeInBits / 8;

            mac = new byte[cipher.getBlockSize()];

            buf    = new byte[cipher.getBlockSize()];
            bufOff = 0;
        }
Пример #4
0
        /// <summary>
        /// Create a configuration for a block cipher.
        /// </summary>
        /// <param name="cipher">Block cipher to use.</param>
        /// <param name="mode">Mode of operation for the cipher.</param>
        /// <param name="padding">Padding scheme to use with the mode, where necessary (e.g. CBC).</param>
        /// <param name="keySize">Key size to use, in bits.</param>
        /// <param name="blockSize">Cipher block size to use, in bits.</param>
        /// <returns>Block cipher configuration DTO.</returns>
        public static CipherConfiguration CreateBlockCipherConfiguration(BlockCipher cipher,
                                                                         BlockCipherMode mode, BlockCipherPadding padding, int?keySize = null, int?blockSize = null)
        {
            var config = new CipherConfiguration {
                Type = CipherType.Block
            };

            // Set the key size
            int keySizeNonNull = keySize ?? Athena.Cryptography.BlockCiphers[cipher].DefaultKeySizeBits;

            if (keySize == null || Athena.Cryptography.BlockCiphers[cipher].AllowableKeySizesBits.Contains(keySizeNonNull))
            {
                config.KeySizeBits = keySizeNonNull;
            }
            else
            {
                throw new CipherKeySizeException(cipher, keySizeNonNull);
            }

            // Set the block size
            int blockSizeNonNull = blockSize ?? Athena.Cryptography.BlockCiphers[cipher].DefaultBlockSizeBits;

            if (blockSize == null ||
                Athena.Cryptography.BlockCiphers[cipher].AllowableBlockSizesBits.Contains(blockSizeNonNull))
            {
                config.BlockSizeBits = blockSizeNonNull;
            }
            else
            {
                throw new BlockSizeException(cipher, blockSizeNonNull);
            }

            // Set the mode
            if (Athena.Cryptography.BlockCipherModes[mode].PaddingRequirement == PaddingRequirement.Always &&
                padding == BlockCipherPadding.None)
            {
                throw new ArgumentException(mode +
                                            " mode must be used with padding or errors will occur when plaintext length is not equal to or a multiple of the block size.");
            }

            config.ModeName    = mode.ToString();
            config.PaddingName = padding.ToString();
            config.CipherName  = cipher.ToString();

            config.InitialisationVector = new byte[config.BlockSizeBits.Value / 8];
            StratCom.EntropySupplier.NextBytes(config.InitialisationVector);

            return(config);
        }
Пример #5
0
 /// <summary>
 ///     Scheme utillised to 'pad' blocks to full size where required.
 ///     What any unused space in a block is filled with.
 ///     Set to empty if using block cipher in streaming mode.
 /// </summary>
 public void SetPadding(BlockCipherPadding value)
 {
     RawConfiguration.PaddingName = value.ToString();
 }
Пример #6
0
 /**
  * create a standard MAC based on a CBC block cipher. This will produce an
  * authentication code half the length of the block size of the cipher.
  *
  * @param cipher the cipher to be used as the basis of the MAC generation.
  * @param padding the padding to be used to complete the last block.
  */
 public CBCBlockCipherMac(
     BlockCipher cipher,
     BlockCipherPadding padding)
     : this(cipher, (cipher.getBlockSize() * 8) / 2, padding)
 {
 }
Пример #7
0
 /// <summary>
 ///     Instantiates and returns an implementation of the requested padding mode.
 ///     Must be combined with a block cipher for operation. <seealso cref="BlockCipherWrapper" />
 /// </summary>
 /// <returns>
 ///     A <see cref="IBlockCipherPadding" /> object implementing the relevant padding scheme.
 /// </returns>
 public static IBlockCipherPadding CreatePadding(BlockCipherPadding paddingEnum)
 {
     Contract.Requires(paddingEnum != BlockCipherPadding.None, "Cannot instantiate null block cipher padding.");
     return(PaddingInstantiators[paddingEnum]());
 }