/// <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)); }
/** * 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; }
/** * 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; }
/// <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); }
/// <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(); }
/** * 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) { }
/// <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]()); }