/// <summary> /// Serialize a KeyParams class /// </summary> /// /// <param name="KeyObj">A KeyParams class</param> /// /// <returns>A stream containing the KeyParams data</returns> public static Stream Serialize(KeyParams KeyObj) { MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); writer.Write(KeyObj.Key != null ? (short)KeyObj.Key.Length : (short)0); writer.Write(KeyObj.IV != null ? (short)KeyObj.IV.Length : (short)0); writer.Write(KeyObj.IKM != null ? (short)KeyObj.IKM.Length : (short)0); writer.Write(KeyObj.ExtKey != null ? (short)KeyObj.ExtKey.Length : (short)0); if (KeyObj.Key != null) { writer.Write(KeyObj.Key); } if (KeyObj.IV != null) { writer.Write(KeyObj.IV); } if (KeyObj.IKM != null) { writer.Write(KeyObj.IKM); } if (KeyObj.ExtKey != null) { writer.Write(KeyObj.ExtKey); } stream.Seek(0, SeekOrigin.Begin); return(stream); }
/// <summary> /// Compare this KeyParams instance with another /// </summary> /// /// <param name="Obj">KeyParams to compare</param> /// /// <returns>Returns true if equal</returns> public bool Equals(KeyParams Obj) { if (!Compare.IsEqual(Obj.Key, m_Key)) { return(false); } if (!Compare.IsEqual(Obj.IV, m_Iv)) { return(false); } if (!Compare.IsEqual(Obj.IKM, m_Ikm)) { return(false); } if (!Compare.IsEqual(Obj.ExtKey, m_extKey)) { return(false); } return(true); }
/// <summary> /// Create a populated KeyParams class /// </summary> /// /// <param name="KeySize">Size of Key to generate in bytes</param> /// <param name="IVSize">Size of IV to generate in bytes</param> /// <param name="IKMSize">Size of IKM to generate in bytes</param> /// <param name="ExtKey">Size of the file name extension key</param> /// /// <returns>A populated <see cref="KeyParams"/> class</returns> public KeyParams GetKeyParams(int KeySize, int IVSize = 0, int IKMSize = 0, int ExtKey = 0) { KeyParams kp = new KeyParams(); if (KeySize > 0) { kp.Key = Generate(KeySize); } if (IVSize > 0) { kp.IV = Generate(IVSize); } if (IKMSize > 0) { kp.IKM = Generate(IKMSize); } if (ExtKey > 0) { kp.ExtKey = Generate(ExtKey); } return(kp); }
/// <summary> /// Initialize the generator /// </summary> /// /// <param name="Salt">Salt value</param> /// /// <exception cref="CryptoGeneratorException">Thrown if a null Salt is used</exception> public void Initialize(byte[] Salt) { if (Salt == null) throw new CryptoGeneratorException("PKCS5:Initialize", "Salt can not be null!", new ArgumentNullException()); byte[] keyBytes = new byte[_digestMac.DigestSize]; Buffer.BlockCopy(Salt, 0, _Salt, 0, Salt.Length - _digestMac.DigestSize); Buffer.BlockCopy(Salt, _Salt.Length, keyBytes, 0, _digestMac.DigestSize); _macKey = new KeyParams(keyBytes); _isInitialized = true; }
/// <summary> /// Initialize the HMAC. /// <para>Uses the Key field of the KeyParams class.</para> /// </summary> /// /// <param name="KeyParam">KeyParams containing HMAC Key. /// <para>Uses the Key field of the <see cref="KeyParams"/> class. /// Key should be equal in size to the <see cref="DigestSize"/></para> /// </param> public void Initialize(KeyParams KeyParam) { _shaHmac.Initialize(KeyParam); _isInitialized = true; }
/// <summary> /// Processes and stores the clients Auth-Stage Symmetric <see cref="KeyParams"/>, /// decrypted with the servers <see cref="IAsymmetricKeyPair">Asymmetric KeyPair</see>. /// </summary> /// /// <param name="PacketStream">A Stream containing the raw packet data</param> private void ProcessAuthEx(MemoryStream PacketStream) { // get the header DtmPacket pktHdr = new DtmPacket(PacketStream); // read the data byte[] data = new byte[pktHdr.PayloadLength]; PacketStream.Read(data, 0, data.Length); // decrypt the symmetric key byte[] dec = AsymmetricDecrypt(_srvAsmParams, _authKeyPair, data); // deserialize the keyparams structure _cltKeyParams = KeyParams.DeSerialize(new MemoryStream(dec)); }
/// <summary> /// Initialize the symmetric cipher /// </summary> private ICipherMode SymmetricInit(DtmSession Session, KeyParams Key) { ICipherMode cipher = GetSymmetricCipher(Session); cipher.Initialize(true, Key); return cipher; }
/// <summary> /// Initialize the generator /// </summary> /// /// <param name="Salt">Salt value</param> /// <param name="Ikm">Key material</param> /// /// <exception cref="CryptoGeneratorException">Thrown if a null Salt or Ikm is used</exception> public void Initialize(byte[] Salt, byte[] Ikm) { if (Salt == null) throw new CryptoGeneratorException("PKCS5:Initialize", "Salt can not be null!", new ArgumentNullException()); if (Ikm == null) throw new CryptoGeneratorException("PKCS5:Initialize", "IKM can not be null!", new ArgumentNullException()); _Salt = (byte[])Salt.Clone(); _macKey = new KeyParams(Ikm); _isInitialized = true; }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { if (_digestMac != null && _disposeEngine) { _digestMac.Dispose(); _digestMac = null; } if (_macKey != null) { _macKey.Dispose(); _macKey = null; } if (_Salt != null) { Array.Clear(_Salt, 0, _Salt.Length); _Salt = null; } } finally { _isDisposed = true; } } }
/// <summary> /// Initialize the class with a CipherDescription Structure; containing the cipher implementation details, and a <see cref="KeyParams"/> class containing the Key material. /// <para>This constructor creates and configures cryptographic instances based on the cipher description contained in a CipherDescription. /// Cipher modes, padding, and engine classes are destroyed automatically through this classes Dispose() method.</para> /// </summary> /// /// <param name="Encryption">Cipher is an encryptor</param> /// <param name="Header">A <see cref="CipherDescription"/> containing the cipher description</param> /// <param name="KeyParam">A <see cref="KeyParams"/> class containing the encryption Key material</param> /// /// <exception cref="System.ArgumentException">Thrown if an invalid <see cref="CipherDescription">CipherDescription</see> is used</exception> /// <exception cref="System.ArgumentNullException">Thrown if a null <see cref="KeyParams">KeyParams</see> is used</exception> public CompressionCipher(bool Encryption, CipherDescription Header, KeyParams KeyParam) : base(Encryption, Header, KeyParam) { _isCompression = Encryption; }
/// <summary> /// Initialize the VMPC MAC. /// <para>Uses the Key and IV fields of the KeyParams class.</para> /// </summary> /// /// <param name="KeyParam">VMPCMAC Key and IV. /// <para>Uses the Key and IV fields of the <see cref="KeyParams"/> class. /// Key and IV must be between 1 and 768 bytes in length. /// Key and IV should be equal in size.</para> /// </param> /// /// <exception cref="CryptoMacException">Thrown if a null or invalid Key, or IV is used</exception> public void Initialize(KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoMacException("VMPCMAC:Initialize", "VMPCMAC Initialize KeyParams must include a Key!", new ArgumentNullException()); if (KeyParam.IV == null) throw new CryptoMacException("VMPCMAC:Initialize", "VMPCMAC Initialize KeyParams must include an IV!", new ArgumentNullException()); _workingIV = KeyParam.IV; if (_workingIV == null || _workingIV.Length < 1 || _workingIV.Length > 768) throw new CryptoMacException("VMPCMAC:Initialize", "VMPCMAC requires 1 to 768 bytes of IV!", new ArgumentOutOfRangeException()); _workingKey = KeyParam.Key; Reset(); _isInitialized = true; }
/// <summary> /// Serialize a KeyParams class /// </summary> /// /// <param name="KeyObj">A KeyParams class</param> /// /// <returns>A stream containing the KeyParams data</returns> public static Stream Serialize(KeyParams KeyObj) { MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); writer.Write(KeyObj.Key != null ? (short)KeyObj.Key.Length : (short)0); writer.Write(KeyObj.IV != null ? (short)KeyObj.IV.Length : (short)0); writer.Write(KeyObj.IKM != null ? (short)KeyObj.IKM.Length : (short)0); if (KeyObj.Key != null) writer.Write(KeyObj.Key); if (KeyObj.IV != null) writer.Write(KeyObj.IV); if (KeyObj.IKM != null) writer.Write(KeyObj.IKM); stream.Seek(0, SeekOrigin.Begin); return stream; }
/// <summary> /// Initialize the class with a CipherDescription Structure; containing the cipher implementation details, and a <see cref="KeyParams"/> class containing the Key material. /// <para>This constructor creates and configures cryptographic instances based on the cipher description contained in a CipherDescription. /// Cipher modes, padding, and engines are destroyed automatically through this classes Dispose() method.</para> /// </summary> /// /// <param name="Encryption">Cipher is an encryptor</param> /// <param name="Description">A <see cref="CipherDescription"/> containing the cipher description</param> /// <param name="KeyParam">A <see cref="KeyParams"/> class containing the encryption Key material</param> /// /// <exception cref="CryptoProcessingException">Thrown if an invalid <see cref="CipherDescription">CipherDescription</see> or <see cref="KeyParams">KeyParams</see> is used</exception> public PacketCipher(bool Encryption, CipherDescription Description, KeyParams KeyParam) { if (!CipherDescription.IsValid(Description)) throw new CryptoProcessingException("PacketCipher:CTor", "The key Header is invalid!", new ArgumentException()); if (KeyParam == null) throw new CryptoProcessingException("PacketCipher:CTor", "KeyParam can not be null!", new ArgumentNullException()); _disposeEngine = true; _isEncryption = Encryption; _blockSize = Description.BlockSize; _isParallel = false; if (_isStreamCipher = IsStreamCipher((SymmetricEngines)Description.EngineType)) { _streamCipher = GetStreamEngine((SymmetricEngines)Description.EngineType, Description.RoundCount, (Digests)Description.KdfEngine); _streamCipher.Initialize(KeyParam); if (_streamCipher.GetType().Equals(typeof(Fusion))) { if (_isParallel = ((Fusion)_streamCipher).IsParallel) _blockSize = ((Fusion)_streamCipher).ParallelBlockSize; } } else { _cipherEngine = GetCipher((CipherModes)Description.CipherType, (SymmetricEngines)Description.EngineType, Description.RoundCount, Description.BlockSize, (Digests)Description.KdfEngine); _cipherEngine.Initialize(_isEncryption, KeyParam); if (_isCounterMode = _cipherEngine.GetType().Equals(typeof(CTR))) { if (_isParallel = ((CTR)_cipherEngine).IsParallel) _blockSize = ((CTR)_cipherEngine).ParallelBlockSize; } else { if (_cipherEngine.GetType().Equals(typeof(CBC))) { if (_isParallel = ((CBC)_cipherEngine).IsParallel && !((CBC)_cipherEngine).IsEncryption) _blockSize = ((CBC)_cipherEngine).ParallelBlockSize; } else if (_cipherEngine.GetType().Equals(typeof(CFB))) { if (_isParallel = ((CFB)_cipherEngine).IsParallel && !((CFB)_cipherEngine).IsEncryption) _blockSize = ((CFB)_cipherEngine).ParallelBlockSize; } } } }
/// <summary> /// Initialize the Cipher /// </summary> /// /// <param name="KeyParam">Cipher key container. /// <para>Uses the Key and IV fields of KeyParam. /// The <see cref="LegalKeySizes"/> property contains valid Key sizes. /// IV must be 8 bytes in size.</para> /// </param> /// /// <exception cref="System.ArgumentNullException">Thrown if a null key or iv is used</exception> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if an invalid key or iv size is used</exception> public void Initialize(KeyParams KeyParam) { if (KeyParam.IV == null) throw new CryptoSymmetricException("Salsa20:Initialize", "Init parameters must include an IV!", new ArgumentException()); if (KeyParam.IV.Length != 8) throw new CryptoSymmetricException("Salsa20:Initialize", "Requires exactly 8 bytes of IV!", new ArgumentOutOfRangeException()); if (KeyParam.Key == null) throw new CryptoSymmetricException("Salsa20:Initialize", "Key can not be null!", new ArgumentException()); if (KeyParam.Key.Length != 16 && KeyParam.Key.Length != 32) throw new CryptoSymmetricException("Salsa20:Initialize", "Key must be 16 or 32 bytes!", new ArgumentOutOfRangeException()); if (DistributionCode == null) { if (KeyParam.Key.Length == 16) _dstCode = (byte[])TAU.Clone(); else _dstCode = (byte[])SIGMA.Clone(); } Reset(); SetKey(KeyParam.Key, KeyParam.IV); _isInitialized = true; }
/// <summary> /// Initialize the Cipher MAC. /// <para>Uses the Key field, and optionally the IV field of the KeyParams class.</para> /// </summary> /// /// <param name="KeyParam">A <see cref="KeyParams"/> containing the cipher Key and optional IV. /// <para>Uses the Key field of the KeyParams parameter, and optionally the IV. /// Key size must be one of the <c>LegalKeySizes</c> of the underlying cipher. /// IV size must be the ciphers blocksize. /// </para> /// </param> /// /// <exception cref="CryptoMacException">Thrown if an invalid Input size is chosen</exception> public void Initialize(KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoMacException("CMAC:Initialize", "Key can not be null!", new ArgumentNullException()); byte[] tmpIv; if (KeyParam.IV == null || KeyParam.IV.Length != _blockSize) tmpIv = new byte[_blockSize]; else tmpIv = KeyParam.IV; // convert for cipher KeyParams key = new KeyParams(KeyParam.Key, tmpIv); _cipherMode.Initialize(true, key); _L = new byte[_tmpZeroes.Length]; _cipherMode.Transform(_tmpZeroes, 0, _L, 0); _LU = DoubleLu(_L); _LU2 = DoubleLu(_LU); _cipherMode.Initialize(true, key); _isInitialized = true; }
/// <summary> /// Initialize the Cipher /// </summary> /// /// <param name="KeyParam">Cipher key container. The <see cref="LegalKeySizes"/> property contains valid sizes</param> /// /// <exception cref="CryptoSymmetricException">Thrown if an invalid key or iv is used</exception> public void Initialize(KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoSymmetricException("Fusion:Initialize", "Invalid key! Key can not be null.", new ArgumentNullException()); if (KeyParam.Key.Length < LegalKeySizes[0]) throw new CryptoSymmetricException("Fusion:Initialize", String.Format("Invalid key size! Key must be at least {0} bytes ({1} bit).", LegalKeySizes[0], LegalKeySizes[0] * 8), new ArgumentOutOfRangeException()); if ((KeyParam.Key.Length - _keyEngine.DigestSize) % _keyEngine.BlockSize != 0) throw new CryptoSymmetricException("Fusion:Initialize", String.Format("Invalid key size! Key must be (length - IKm length: {0} bytes) + multiple of {1} block size.", _keyEngine.DigestSize, _keyEngine.BlockSize), new ArgumentOutOfRangeException()); if (KeyParam.IV == null) throw new CryptoSymmetricException("Fusion:Initialize", "Invalid IV! IV can not be null.", new ArgumentNullException()); if (KeyParam.IV.Length != BLOCK_SIZE) throw new CryptoSymmetricException("Fusion:Initialize", String.Format("Invalid IV size! IV must be at exactly {0} bytes ({1} bit).", BLOCK_SIZE, BLOCK_SIZE * 8), new ArgumentOutOfRangeException()); // get the iv _ctrVector = (byte[])KeyParam.IV.Clone(); // expand the key _expKey = ExpandKey(KeyParam.Key); // ready to transform data _isInitialized = true; }
/// <summary> /// Initialize the Cipher. /// </summary> /// /// <param name="Encryption">Using Encryption or Decryption mode</param> /// <param name="KeyParam">Cipher key container. <para>The <see cref="LegalKeySizes"/> property contains valid sizes.</para></param> /// /// <exception cref="CryptoSymmetricException">Thrown if a null or invalid key is used</exception> public void Initialize(bool Encryption, KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoSymmetricException("SPX:Initialize", "Invalid key! Key can not be null.", new ArgumentNullException()); if (KeyParam.Key.Length != 16 && KeyParam.Key.Length != 24 && KeyParam.Key.Length != 32 && KeyParam.Key.Length != 64) throw new CryptoSymmetricException("SPX:Initialize", "Invalid key size! Valid sizes are 16, 24, 32 and 64 bytes.", new ArgumentOutOfRangeException()); _isEncryption = Encryption; _expKey = ExpandKey(KeyParam.Key); }
private void ParallelTest() { byte[] data; byte[] dec1; byte[] dec2; byte[] enc1; byte[] enc2; int blockSize; KeyParams keyParam = new KeyParams(GetBytes(32), GetBytes(16)); // CTR mode using (CTR cipher = new CTR(new RDX())) { data = GetBytes(1036); // how to calculate an ideal block size int plen = (data.Length / cipher.ParallelMinimumSize) * cipher.ParallelMinimumSize; // you can factor it up or down or use a default if (plen > cipher.ParallelMaximumSize) plen = 1024; // set parallel block size cipher.ParallelBlockSize = plen; // encrypt // // parallel cipher.Initialize(true, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; enc1 = Transform1(cipher, data, blockSize); // normal mode cipher.Initialize(true, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; enc2 = Transform1(cipher, data, blockSize); // decrypt cipher.Initialize(false, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; dec1 = Transform1(cipher, enc1, blockSize); cipher.Initialize(false, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; dec2 = Transform1(cipher, enc1, blockSize); } if (Compare.AreEqual(enc1, enc2) == false) throw new Exception("Parallel CTR: Encrypted output is not equal!"); if (Compare.AreEqual(dec1, dec2) == false) throw new Exception("Parallel CTR: Decrypted output is not equal!"); OnProgress(new TestEventArgs("Passed Parallel CTR encryption and decryption tests..")); // CBC mode using (CBC cipher = new CBC(new RDX())) { // must be divisible by block size, add padding if required data = GetBytes(2048); // encrypt cipher.ParallelBlockSize = 1024; // encrypt only in normal mode for cbc cipher.Initialize(true, keyParam); blockSize = cipher.BlockSize; enc1 = Transform1(cipher, data, blockSize); // decrypt cipher.Initialize(false, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; dec1 = Transform1(cipher, enc1, blockSize); cipher.Initialize(false, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; dec2 = Transform1(cipher, enc1, blockSize); } if (Compare.AreEqual(dec1, dec2) == false) throw new Exception("Parallel CBC: Decrypted output is not equal!"); OnProgress(new TestEventArgs("Passed Parallel CBC decryption tests..")); // CFB mode using (CFB cipher = new CFB(new RDX())) { // must be divisible by block size, add padding if required data = GetBytes(2048); // encrypt cipher.ParallelBlockSize = 1024; // encrypt only in normal mode for cfb cipher.Initialize(true, keyParam); blockSize = cipher.BlockSize; enc1 = Transform1(cipher, data, blockSize); // decrypt cipher.Initialize(false, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; dec1 = Transform1(cipher, enc1, blockSize); cipher.Initialize(false, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; dec2 = Transform1(cipher, enc1, blockSize); } if (Compare.AreEqual(dec1, dec2) == false) throw new Exception("Parallel CFB: Decrypted output is not equal!"); if (Compare.AreEqual(dec1, data) == false) throw new Exception("Parallel CFB: Decrypted output is not equal!"); OnProgress(new TestEventArgs("Passed Parallel CFB decryption tests..")); // dispose container keyParam.Dispose(); }
/// <summary> /// Initialize the Cipher /// </summary> /// /// <param name="Encryption">Cipher is used. for encryption, false to decrypt</param> /// <param name="KeyParam">The KeyParams containing key and vector</param> /// /// <exception cref="CryptoSymmetricException">Thrown if a null Key or IV is used</exception> public void Initialize(bool Encryption, KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoSymmetricException("CTR:Initialize", "Key can not be null!", new ArgumentNullException()); if (KeyParam.IV == null) throw new CryptoSymmetricException("CTR:Initialize", "IV can not be null!", new ArgumentNullException()); _blockCipher.Initialize(true, KeyParam); _ctrVector = KeyParam.IV; _isEncryption = Encryption; _isInitialized = true; }
/// <summary> /// Initialize the class and working variables. /// <para>When this constructor is used, <see cref="Initialize(KeyParams)"/> is called automatically.</para> /// </summary> /// /// <param name="Digest">Message Digest instance</param> /// <param name="Key">HMAC Key; passed to HMAC Initialize() through constructor</param> /// <param name="DisposeEngine">Dispose of digest engine when <see cref="Dispose()"/> on this class is called</param> /// /// <exception cref="CryptoMacException">Thrown if a null digest is used</exception> public HMAC(IDigest Digest, byte[] Key, bool DisposeEngine = true) { if (Digest == null) throw new CryptoMacException("HMAC:Ctor", "Digest can not be null!", new ArgumentNullException()); _disposeEngine = DisposeEngine; _msgDigest = Digest; _digestSize = Digest.DigestSize; _blockSize = Digest.BlockSize; _inputPad = new byte[_blockSize]; _outputPad = new byte[_blockSize]; KeyParams keyParam = new KeyParams(Key); Initialize(keyParam); keyParam.Dispose(); }
/// <summary> /// Initialize the Cipher /// </summary> /// /// <param name="Encryption">Cipher is used. for encryption, false to decrypt</param> /// <param name="KeyParam">KeyParam containing key and vector</param> /// /// <exception cref="CryptoSymmetricException">Thrown if a null Key or IV is used</exception> public void Initialize(bool Encryption, KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoSymmetricException("CBC:Initialize", "Key can not be null!", new ArgumentNullException()); if (KeyParam.IV == null) throw new CryptoSymmetricException("CBC:Initialize", "IV can not be null!", new ArgumentNullException()); _blockCipher.Initialize(Encryption, KeyParam); _cbcIv = KeyParam.IV; _cbcNextIv = new byte[_cbcIv.Length]; _isEncryption = Encryption; _isInitialized = true; }
/// <summary> /// Send the servers Auth-Stage Symmetric <see cref="KeyParams"/>, encrypted with the clients Public Key. /// <para>The packet header; <see cref="DtmPacket"/>, contains the message type, payload length, sequence number, and exchange state. /// The payload is the servers Auth-Stage Symmetric KeyParams, encrypted with the clients Asymmetric Public Key.</para> /// </summary> /// /// <returns>A raw packet containing the packet header, and the servers Auth-Stage Symmetric Key</returns> private MemoryStream CreateAuthEx() { // create a session key based on servers symmetric session params _srvKeyParams = GenerateSymmetricKey(_srvIdentity.Session); // serialize the keyparams structure byte[] srvKrw = ((MemoryStream)KeyParams.Serialize(_srvKeyParams)).ToArray(); // encrypt the servers symmetric key with the clients public key byte[] enc = AsymmetricEncrypt(_cltAsmParams, _cltPublicKey, srvKrw); // payload container MemoryStream pldStm = new MemoryStream(enc); // stage completed _exchangeState = DtmExchangeFlags.AuthEx; // optional delay before transmission if (_dtmParameters.MaxSymKeyDelayMS > 0) SendWait(_dtmParameters.MaxSymKeyDelayMS, _dtmParameters.MaxSymKeyDelayMS / 2); return pldStm; }
/// <summary> /// Write the key data from the key stream /// </summary> /// /// <param name="KeyStream">The stream containing a session key</param> /// <param name="KeyParam">KeyParams class containing the keying material</param> public static void SetKey(Stream KeyStream, KeyParams KeyParam) { byte[] key = KeyParam.Key; byte[] iv = KeyParam.IV; KeyStream.Seek(HDR_SIZE, SeekOrigin.Begin); KeyStream.Write(key, 0, key.Length); KeyStream.Write(iv, 0, iv.Length); }
/// <summary> /// Initialize the generator /// </summary> /// /// <param name="Salt">Salt value</param> /// <param name="Ikm">Key material</param> /// <param name="Nonce">Nonce value</param> /// /// <exception cref="CryptoGeneratorException">Thrown if a null Salt or Ikm is used</exception> public void Initialize(byte[] Salt, byte[] Ikm, byte[] Nonce) { if (Salt == null) throw new CryptoGeneratorException("PKCS5:Initialize", "Salt can not be null!", new ArgumentNullException()); if (Ikm == null) throw new CryptoGeneratorException("PKCS5:Initialize", "IKM can not be null!", new ArgumentNullException()); _macKey = new KeyParams(Ikm); _Salt = new byte[Salt.Length + Nonce.Length]; Buffer.BlockCopy(Salt, 0, _Salt, 0, Salt.Length); Buffer.BlockCopy(Nonce, 0, _Salt, Salt.Length, Nonce.Length); _isInitialized = true; }
/// <summary> /// Initialize the HMAC. /// <para>Uses the Key field of the KeyParams class.</para> /// </summary> /// /// <param name="KeyParam">The HMAC Key. /// <para>Uses the Key field of the <see cref="KeyParams"/> class. /// Key should be equal in size to the <see cref="DigestSize"/> value.</para> /// </param> /// /// <exception cref="CryptoMacException">Thrown if the Key is null or less than digest size</exception> public void Initialize(KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoMacException("HMAC:Initialize", "Key can not be null!", new ArgumentNullException()); _msgDigest.Reset(); int keyLength = KeyParam.Key.Length; // compress to digest size if (KeyParam.Key.Length > _blockSize) { _msgDigest.BlockUpdate(KeyParam.Key, 0, KeyParam.Key.Length); _msgDigest.DoFinal(_inputPad, 0); keyLength = _digestSize; } else { Array.Copy(KeyParam.Key, 0, _inputPad, 0, keyLength); } Array.Clear(_inputPad, keyLength, _blockSize - keyLength); Array.Copy(_inputPad, 0, _outputPad, 0, _blockSize); XOR(_inputPad, IPAD); XOR(_outputPad, OPAD); // initialise the digest _msgDigest.BlockUpdate(_inputPad, 0, _inputPad.Length); _isInitialized = true; }
public EngineSpeedTest(SymmetricEngines Engine, CipherModes Mode, int DataSize, int KeySize, int Rounds, bool Encryption, bool Parallel, TestTypes TestType = TestTypes.FileIO) { _cipherType = Mode; _dataSize = DataSize; _roundCount = Rounds; _engineType = Engine; _isEncryption = Encryption; _isParallel = Parallel; _keySize = KeySize; _keyParam = GetKeyParams(); _testType = TestType; if (IsStreamCipher()) { _streamCipher = GetStreamEngine(); _streamCipher.Initialize(_keyParam); if (_isParallel && _engineType == SymmetricEngines.Fusion || _engineType == SymmetricEngines.Salsa) { if (_dataSize > MB100) _blockSize = MB100; else if (DataSize > MB10) _blockSize = MB10; else if (DataSize > MB1) _blockSize = MB1; else _blockSize = 1024; } else { _blockSize = 64000; } } else { _cipherEngine = GetCipher(); _cipherEngine.Initialize(_isEncryption, _keyParam); // set parallel if (_cipherEngine.GetType().Equals(typeof(CTR))) ((CTR)_cipherEngine).IsParallel = _isParallel; else if (_cipherEngine.GetType().Equals(typeof(CBC))) ((CBC)_cipherEngine).IsParallel = _isParallel; else if (_cipherEngine.GetType().Equals(typeof(CFB))) ((CFB)_cipherEngine).IsParallel = _isParallel; // set block if (_isParallel && (_cipherType.Equals(CipherModes.CTR) || _cipherType.Equals(CipherModes.CBC) && !_isEncryption || _cipherType.Equals(CipherModes.CFB) && !_isEncryption)) { if (_dataSize > MB100) _blockSize = MB100; else if (DataSize > MB10) _blockSize = MB10; else if (DataSize > MB1) _blockSize = MB1; else _blockSize = 1024; if (_cipherEngine.GetType().Equals(typeof(CTR))) ((CTR)_cipherEngine).ParallelBlockSize = _blockSize; else if (_cipherEngine.GetType().Equals(typeof(CBC))) ((CBC)_cipherEngine).ParallelBlockSize = _blockSize; else if (_cipherEngine.GetType().Equals(typeof(CFB))) ((CFB)_cipherEngine).ParallelBlockSize = _blockSize; } else { _blockSize = _cipherEngine.BlockSize; } } _inputBuffer = new byte[_blockSize]; _outputBuffer = new byte[_blockSize]; }
/// <summary> /// Sends the servers primary-stage Symmetric <see cref="KeyParams"/>. /// </summary> /// /// <returns>A Stream containing the raw packet data</returns> private MemoryStream CreatePrimary() { // create the primary session key KeyParams tmpKey = GenerateSymmetricKey(_srvIdentity.Session); // serialize the keyparams structure byte[] srvKrw = ((MemoryStream)KeyParams.Serialize(tmpKey)).ToArray(); // encrypt the symmetric key with the primary asymmetric cipher byte[] enc = AsymmetricEncrypt(_cltAsmParams, _cltPublicKey, srvKrw); // pad the encrypted key with random enc = WrapMessage(enc, _dtmParameters.MaxSymKeyAppend, _dtmParameters.MaxSymKeyPrePend); // encrypt the result with the auth symmetric key enc = SymmetricTransform(_srvSymProcessor, enc); // clear auth key _srvKeyParams.Dispose(); // swap to primary symmetric key _srvKeyParams = tmpKey; // payload container MemoryStream pldStm = new MemoryStream(enc); // stage completed _exchangeState = DtmExchangeFlags.Primary; return pldStm; }
/// <summary> /// Initialize the Cipher /// </summary> /// /// <param name="Encryption">Cipher is used. for encryption, false to decrypt</param> /// <param name="KeyParam">The KeyParams containing key and vector</param> /// /// <exception cref="CryptoSymmetricException">Thrown if a null Key or IV is used</exception> public void Initialize(bool Encryption, KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoSymmetricException("OFB:Initialize", "Key can not be null!", new ArgumentNullException()); if (KeyParam.IV == null) throw new CryptoSymmetricException("OFB:Initialize", "IV can not be null!", new ArgumentNullException()); _blockCipher.Initialize(true, KeyParam); byte[] iv = KeyParam.IV; if (iv.Length < _ofbIv.Length) { // prepend the supplied IV with zeros per FIPS PUB 81 Array.Copy(iv, 0, _ofbIv, _ofbIv.Length - iv.Length, iv.Length); for (int i = 0; i < _ofbIv.Length - iv.Length; i++) _ofbIv[i] = 0; } else { Array.Copy(iv, 0, _ofbIv, 0, _ofbIv.Length); } _isEncryption = Encryption; _isInitialized = true; }
/// <summary> /// Processes and stores the clients primary-stage Symmetric <see cref="KeyParams"/>, /// decrypted with the servers <see cref="IAsymmetricKeyPair">Asymmetric KeyPair</see>. /// </summary> /// /// <param name="PacketStream">A Stream containing the raw packet data</param> private void ProcessPrimary(MemoryStream PacketStream) { // get the header DtmPacket pktHdr = new DtmPacket(PacketStream); // read the data byte[] data = new byte[pktHdr.PayloadLength]; PacketStream.Read(data, 0, data.Length); // decrypt using the auth stage symmetric key data = SymmetricTransform(_cltSymProcessor, data); // remove random padding data = UnwrapMessage(data); // decrypt the symmetric key using the primary asymmetric cipher byte[] dec = AsymmetricDecrypt(_srvAsmParams, _primKeyPair, data); // clear auth key _cltKeyParams.Dispose(); // deserialize the primary session key _cltKeyParams = KeyParams.DeSerialize(new MemoryStream(dec)); }
/// <summary> /// Initialize the Cipher. /// </summary> /// /// <param name="Encryption">Using Encryption or Decryption mode</param> /// <param name="KeyParam">Cipher key container. <para>The <see cref="LegalKeySizes"/> property contains valid sizes.</para></param> /// /// <exception cref="CryptoSymmetricException">Thrown if a null or invalid key is used</exception> public void Initialize(bool Encryption, KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoSymmetricException("RSM:Initialize", "Invalid key! Key can not be null.", new ArgumentNullException()); if (KeyParam.Key.Length < LegalKeySizes[0]) throw new CryptoSymmetricException("RSM:Initialize", String.Format("Invalid key size! Key must be at least {0} bytes ({1} bit).", LegalKeySizes[0], LegalKeySizes[0] * 8), new ArgumentOutOfRangeException()); if ((KeyParam.Key.Length - _keyEngine.DigestSize) % _keyEngine.BlockSize != 0) throw new CryptoSymmetricException("RSM:Initialize", String.Format("Invalid key size! Key must be (length - IKm length: {0} bytes) + multiple of {1} block size.", _keyEngine.DigestSize, _keyEngine.BlockSize), new ArgumentOutOfRangeException()); _isEncryption = Encryption; // expand the key _expKey = ExpandKey(KeyParam.Key, Encryption); // ready to transform data _isInitialized = true; }
/// <summary> /// Tear down the connection; destroys all structures provided by this class /// </summary> private void TearDown() { if (_rndGenerator != null) { _rndGenerator.Dispose(); _rndGenerator = null; } if (_authKeyPair != null) { _authKeyPair.Dispose(); _authKeyPair = null; } if (_cltAsmParams != null) { _cltAsmParams.Dispose(); _cltAsmParams = null; } if (_cltPublicKey != null) { _cltPublicKey.Dispose(); _cltPublicKey = null; } if (_primKeyPair != null) { _primKeyPair.Dispose(); _primKeyPair = null; } // cipher streaming managed through class if (SessionEstablished == null || _disposeEngines == true) { if (_cltKeyParams != null) { _cltKeyParams.Dispose(); _cltKeyParams = null; } if (_srvKeyParams != null) { _srvKeyParams.Dispose(); _srvKeyParams = null; } if (_srvSymProcessor != null) { _srvSymProcessor.Dispose(); _srvSymProcessor = null; } if (_cltSymProcessor != null) { _cltSymProcessor.Dispose(); _cltSymProcessor = null; } } _bufferCount = 0; _bytesSent = 0; _bytesReceived = 0; _cltIdentity.Reset(); _fileCounter = 0; _maxSendCounter = 0; _maxSendAttempts = MAXSNDATTEMPT; _rcvSequence = 0; _sndSequence = 0; }
/// <summary> /// Initialize the Cipher /// </summary> /// /// <param name="Encryption">Cipher is used. for encryption, false to decrypt</param> /// <param name="KeyParam">KeyParams containing key and vector</param> /// /// <exception cref="CryptoSymmetricException">Thrown if a null Key or IV is used</exception> public void Initialize(bool Encryption, KeyParams KeyParam) { if (KeyParam.Key == null) throw new CryptoSymmetricException("CFB:Initialize", "Key can not be null!", new ArgumentNullException()); if (KeyParam.IV == null) throw new CryptoSymmetricException("CFB:Initialize", "IV can not be null!", new ArgumentNullException()); byte[] iv = KeyParam.IV; int diff = _cfbIv.Length - iv.Length; Buffer.BlockCopy(iv, 0, _cfbIv, diff, iv.Length); Array.Clear(_cfbIv, 0, diff); _blockCipher.Initialize(true, KeyParam); _isEncryption = Encryption; _isInitialized = true; }