source: trunk/CrypPlugins/Twofish/Twofish.cs @ 226

Last change on this file since 226 was 226, checked in by Gerhard Junker, 13 years ago

2FISH - first fixes

File size: 11.7 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////////////////////
2// CrypTool V2
3// © 2008 - Gerhard Junker
4// Apache License see http://www.apache.org/licenses/
5//
6// $HeadURL: https://www.cryptool.org/svn/CrypTool2/trunk/SSCext/TwofishBase.cs $
7//////////////////////////////////////////////////////////////////////////////////////////////////
8// $Revision:: 157                                                                            $://
9// $Author:: junker                                                                           $://
10// $Date:: 2008-12-17 08:07:48 +0100 (Mi, 17 Dez 2008)                                        $://
11//////////////////////////////////////////////////////////////////////////////////////////////////
12
13// more about at http://www.schneier.com/twofish.html
14
15using System;
16using System.Collections.Generic;
17using System.Text;
18using Cryptool.PluginBase;
19using Cryptool.PluginBase.Cryptography;
20using Cryptool.PluginBase.IO;
21using Cryptool.PluginBase.Miscellaneous;
22using System.ComponentModel;
23using System.Security.Cryptography;
24
25namespace Twofish
26{
27  [Author("Gerhard Junker", null, "private project member", null)]
28  [PluginInfo(false, "Twofish", "Twofish -- cipher",
29    "Twofish/DetailedDescription/Description.xaml", "Twofish/Images/Twofish.png", "Twofish/Images/encrypt.png", "Twofish/Images/decrypt.png")]
30  [EncryptionType(EncryptionType.SymmetricBlock)]
31  public class Twofish : IEncryption
32  {
33      private byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
34
35
36    /// <summary>
37    /// Initializes a new instance of the <see cref="Twofish"/> class.
38    /// </summary>
39    public Twofish()
40    {
41      settings = new TwofishSettings();
42    }
43
44    #region IPlugin Member
45
46
47#pragma warning disable 67
48    public event StatusChangedEventHandler  OnPluginStatusChanged;
49    public event GuiLogNotificationEventHandler  OnGuiLogNotificationOccured;
50    public event PluginProgressChangedEventHandler  OnPluginProgressChanged;
51#pragma warning restore
52
53
54    TwofishSettings settings;
55    /// <summary>
56    /// Gets or sets the settings.
57    /// </summary>
58    /// <value>The settings.</value>
59    public ISettings Settings
60    {
61      get
62      {
63        return settings;
64      }
65      set
66      {
67        settings = (TwofishSettings)value;
68        OnPropertyChanged("Settings");
69      }
70    }
71
72    /// <summary>
73    /// Provide all presentation stuff in this user control, it will be opened in an tab.
74    /// Return null if your plugin has no presentation.
75    /// </summary>
76    /// <value>The presentation.</value>
77    public System.Windows.Controls.UserControl Presentation
78    {
79      get
80      {
81        return null;
82      }
83    }
84
85    public System.Windows.Controls.UserControl QuickWatchPresentation
86    {
87      get
88      {
89        return null;
90      }
91    }
92
93    public void PreExecution()
94    {
95    }
96
97    public void Execute()
98    {
99      Crypt();
100    }
101
102    public void PostExecution()
103    {
104    }
105
106    public void Pause()
107    {
108    }
109
110    public void Stop()
111    {
112    }
113
114    public void Initialize()
115    {
116    }
117
118    /// <summary>
119    /// Will be called from editor when element is deleted from worksapce.
120    /// Releases unmanaged and - optionally - managed resources
121    /// </summary>
122    public void Dispose()
123    {
124      foreach (CryptoolStream stream in listCryptoolStreamsOut)
125      {
126        stream.Close();
127      }
128      listCryptoolStreamsOut.Clear();
129    }
130
131    #endregion
132
133
134    #region Input inputdata
135
136    // Input inputdata
137                private byte[] inputdata = { };
138
139                /// <summary>
140                /// Notifies the update input.
141                /// </summary>
142                private void NotifyUpdateInput()
143                {
144                        OnPropertyChanged("InputStream");
145                        OnPropertyChanged("InputData");
146                }
147
148                /// <summary>
149                /// Gets or sets the input inputdata.
150                /// </summary>
151                /// <value>The input inputdata.</value>
152                [PropertyInfo(Direction.Input, "Input Data Stream", "Input data stream to process", "",
153      false, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
154                public CryptoolStream InputStream
155                {
156                        get
157                        {
158                                CryptoolStream inputStream = new CryptoolStream();
159                                inputStream.OpenRead(this.GetPluginInfoAttribute().Caption, inputdata);
160                                return inputStream;
161                        }
162                        set
163                        {
164        if (null == value)
165        {
166          inputdata = new byte[0];
167          return;
168        }
169
170                                long len = value.Length;
171                                inputdata = new byte[len];
172
173                                for (long i = 0; i < len; i++)
174                                        inputdata[i] = (byte)value.ReadByte();
175
176                                NotifyUpdateInput();
177                        }
178                }
179
180                /// <summary>
181                /// Gets the input data.
182                /// </summary>
183                /// <value>The input data.</value>
184                [PropertyInfo(Direction.Input, "Input Data", "Input Data to process", "",
185      false, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
186                public byte[] InputData
187                {
188                        get
189                        {
190                                return inputdata;
191                        }
192                        set
193                        {
194        if (null == value)
195        {
196          inputdata = new byte[0];
197          return;
198        }
199                                long len = value.Length;
200                                inputdata = new byte[len];
201
202                                for (long i = 0; i < len; i++)
203                                        inputdata[i] = value[i];
204
205                                NotifyUpdateInput();
206                        }
207                }
208                #endregion
209
210    #region Key data
211
212    // Salt Data
213    private byte[] key = { };
214
215    /// <summary>
216    /// Notifies the update key.
217    /// </summary>
218    private void NotifyUpdateKey()
219    {
220      OnPropertyChanged("KeyStream");
221      OnPropertyChanged("KeyData");
222    }
223
224    /// <summary>
225    /// Gets or sets the key data.
226    /// </summary>
227    /// <value>The key data.</value>
228    [PropertyInfo(Direction.Input, "Key Stream", "Key - Input key data",
229      "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
230    public CryptoolStream KeyStream
231    {
232      get
233      {
234        CryptoolStream keyDataStream = new CryptoolStream();
235        keyDataStream.OpenRead(this.GetPluginInfoAttribute().Caption, key);
236        return keyDataStream;
237      }
238      set
239      {
240        if (null == value)
241          return;
242
243        long len = value.Length;
244        key = new byte[len];
245
246        for (long i = 0; i < len; i++)
247          key[i] = (byte)value.ReadByte();
248
249        NotifyUpdateKey();
250        GuiLogMessage("KeyStream changed.", NotificationLevel.Debug);
251      }
252    }
253
254    /// <summary>
255    /// Gets or sets the key data.
256    /// </summary>
257    /// <value>The key data.</value>
258    [PropertyInfo(Direction.Input, "Key Data", "Key - Input key data",
259      "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
260    public byte[] KeyData
261    {
262      get
263      {
264        return key;
265      }
266
267      set
268      {
269        long len = value.Length;
270        key = new byte[len];
271
272        for (long i = 0; i < len; i++)
273          key[i] = value[i];
274
275        NotifyUpdateKey();
276        GuiLogMessage("KeyData changed.", NotificationLevel.Debug);
277      }
278    }
279
280    #endregion
281
282    [PropertyInfo(Direction.Input, "IV", "Initialization Vector", "",
283    false, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
284    public byte[] IV
285    {
286        get
287        {
288            return iv;
289        }
290        set
291        {
292            Array.Clear(iv, 0, iv.Length);
293
294            if (null == value)
295                return;
296
297            for (int i = 0; i < value.Length && i < iv.Length; i++)
298                iv[i] = value[i];
299
300            NotifyUpdateInput();
301            GuiLogMessage("InputData changed.", NotificationLevel.Debug);
302        }
303    }
304
305
306
307    #region Output
308
309    // Output
310    private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
311    private byte[] outputData = { };
312
313    /// <summary>
314    /// Notifies the update output.
315    /// </summary>
316    private void NotifyUpdateOutput()
317    {
318      OnPropertyChanged("OutputStream");
319      OnPropertyChanged("OutputData");
320    }
321
322
323    /// <summary>
324    /// Gets or sets the output inputdata stream.
325    /// </summary>
326    /// <value>The output inputdata stream.</value>
327    [PropertyInfo(Direction.Output, "Output Stream", "Output stream", "",
328      true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null) ]
329    public CryptoolStream OutputStream
330    {
331      get
332      {
333        CryptoolStream outputDataStream = null;
334        if (outputData != null)
335        {
336          outputDataStream = new CryptoolStream();
337          outputDataStream.OpenRead(this.GetPluginInfoAttribute().Caption, outputData);
338          listCryptoolStreamsOut.Add(outputDataStream);
339        }
340        return outputDataStream;
341      }
342    }
343
344    /// <summary>
345    /// Gets the output inputdata.
346    /// </summary>
347    /// <value>The output inputdata.</value>
348    [PropertyInfo(Direction.Output, "Output Data", "Output data", "",
349      true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
350    public byte[] OutputData
351    {
352      get
353      {
354        return this.outputData;
355      }
356    }
357
358    #endregion
359
360
361
362    #region INotifyPropertyChanged Member
363
364    public event PropertyChangedEventHandler  PropertyChanged;
365    /// <summary>
366    /// Called when [property changed].
367    /// </summary>
368    /// <param name="name">The name.</param>
369    protected void OnPropertyChanged(string name)
370    {
371      if (PropertyChanged != null)
372      {
373        if (name == "Settings")
374        {
375          Crypt();
376        }
377        else
378          PropertyChanged(this, new PropertyChangedEventArgs(name));
379      }
380    }
381
382
383    /// <summary>
384    /// GUIs the log message.
385    /// </summary>
386    /// <param name="message">The message.</param>
387    /// <param name="logLevel">The log level.</param>
388    private void GuiLogMessage(string message, NotificationLevel logLevel)
389    {
390      EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this,
391        new GuiLogEventArgs(message, this, logLevel));
392    }
393
394    #endregion
395
396
397    private void Crypt()
398    {
399      // fit key to correct length
400      byte[] k2 = new byte[settings.KeyLength / 8];
401      for (int i = 0; i < settings.KeyLength / 8; i++)
402        if (i < key.Length)
403          k2[i] = key[i];
404        else
405          k2[i] = 0;
406   
407
408      TwofishManaged tf = TwofishManaged.Create();
409
410      tf.Mode = (settings.Mode == 0) ? CipherMode.CBC : CipherMode.ECB;
411     
412      int pos = 0;
413
414      int len = inputdata.Length;
415      if (settings.Action == 0) // input padding
416      {
417          if (len % 16 != 0)
418              len += (16 - len % 16);
419      }
420      if (outputData.Length != len) 
421        outputData = new byte[len];
422
423      switch (settings.Action)
424      {
425        case 0: // encrypt
426          {
427            ICryptoTransform encrypt =  tf.CreateEncryptor(k2, iv);
428
429            while (inputdata.Length - pos > encrypt.InputBlockSize)
430            {
431              pos += encrypt.TransformBlock(inputdata, pos, encrypt.InputBlockSize, outputData, pos);
432            }
433            byte[] final = encrypt.TransformFinalBlock(inputdata, pos, inputdata.Length - pos);
434            Array.Copy(final, 0, outputData, pos, 16);
435            encrypt.Dispose();
436            break;
437          }
438        case 1: // decrypt
439          {
440            ICryptoTransform decrypt =  tf.CreateDecryptor(k2, iv);
441
442            while (inputdata.Length - pos > decrypt.InputBlockSize)
443            {
444              pos += decrypt.TransformBlock(inputdata, pos, decrypt.InputBlockSize, outputData, pos);
445            }
446            byte[] final = decrypt.TransformFinalBlock(inputdata, pos, 16);
447
448              for (int i = pos; i < outputData.Length; i++)
449                outputData[i] = final[i - pos];
450
451            decrypt.Dispose();
452            break;
453          }
454      }
455
456      NotifyUpdateOutput();
457    }
458
459  }
460}
Note: See TracBrowser for help on using the repository browser.