keepass2android/src/TwofishCipher/Twofish.cs
2013-09-03 23:10:59 +02:00

122 lines
3.8 KiB
C#

/*
A C# implementation of the Twofish cipher
By Shaun Wilde
An article on integrating a C# implementation of the Twofish cipher into the
.NET framework.
http://www.codeproject.com/KB/recipes/twofish_csharp.aspx
The Code Project Open License (CPOL) 1.02
http://www.codeproject.com/info/cpol10.aspx
Download a copy of the CPOL.
http://www.codeproject.com/info/CPOL.zip
*/
using System;
using System.Diagnostics;
using System.Security.Cryptography;
namespace TwofishCipher.Crypto
{
/// <summary>
/// Summary description for Twofish encryption algorithm of which more information can be found at http://www.counterpane.com/twofish.html.
/// This is based on the MS cryptographic framework and can therefore be used in place of the RijndaelManaged classes
/// provided by MS in System.Security.Cryptography and the other related classes
/// </summary>
public sealed class Twofish : SymmetricAlgorithm
{
/// <summary>
/// This is the Twofish constructor.
/// </summary>
public Twofish()
{
this.LegalKeySizesValue = new KeySizes[]{new KeySizes(128,256,64)}; // this allows us to have 128,192,256 key sizes
this.LegalBlockSizesValue = new KeySizes[]{new KeySizes(128,128,0)}; // this is in bits - typical of MS - always 16 bytes
this.BlockSize = 128; // set this to 16 bytes we cannot have any other value
this.KeySize = 128; // in bits - this can be changed to 128,192,256
this.Padding = PaddingMode.Zeros;
this.Mode = CipherMode.ECB;
}
/// <summary>
/// Creates an object that supports ICryptoTransform that can be used to encrypt data using the Twofish encryption algorithm.
/// </summary>
/// <param name="key">A byte array that contains a key. The length of this key should be equal to the KeySize property</param>
/// <param name="iv">A byte array that contains an initialization vector. The length of this IV should be equal to the BlockSize property</param>
public override ICryptoTransform CreateEncryptor(byte[] key, byte[] iv)
{
Key = key; // this appears to make a new copy
if (Mode == CipherMode.CBC)
IV = iv;
return new TwofishEncryption(KeySize, ref KeyValue, ref IVValue, ModeValue, TwofishBase.EncryptionDirection.Encrypting);
}
/// <summary>
/// Creates an object that supports ICryptoTransform that can be used to decrypt data using the Twofish encryption algorithm.
/// </summary>
/// <param name="key">A byte array that contains a key. The length of this key should be equal to the KeySize property</param>
/// <param name="iv">A byte array that contains an initialization vector. The length of this IV should be equal to the BlockSize property</param>
public override ICryptoTransform CreateDecryptor(byte[] key, byte[] iv)
{
Key = key;
if (Mode == CipherMode.CBC)
IV = iv;
return new TwofishEncryption(KeySize, ref KeyValue, ref IVValue, ModeValue, TwofishBase.EncryptionDirection.Decrypting);
}
/// <summary>
/// Generates a random initialization Vector (IV).
/// </summary>
public override void GenerateIV()
{
IV = new byte[16]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
}
/// <summary>
/// Generates a random Key. This is only really useful in testing scenarios.
/// </summary>
public override void GenerateKey()
{
Key = new byte[KeySize/8];
// set the array to all 0 - implement a random key generation mechanism later probably based on PRNG
for (int i=Key.GetLowerBound(0);i<Key.GetUpperBound(0);i++)
{
Key[i]=0;
}
}
/// <summary>
/// Override the Set method on this property so that we only support CBC and EBC
/// </summary>
public override CipherMode Mode
{
set
{
switch (value)
{
case CipherMode.CBC:
break;
case CipherMode.ECB:
break;
default:
throw (new CryptographicException("Specified CipherMode is not supported."));
}
this.ModeValue = value;
}
}
}
}