2002-10-23 Sebastien Pouliot <spouliot@videotron.ca>
[mono.git] / mcs / class / corlib / System.Security.Cryptography / TripleDESCryptoServiceProvider.cs
1 //
2 // TripleDESCryptoServiceProvider.cs: Default TripleDES implementation
3 //
4 // Author:
5 //      Sebastien Pouliot (spouliot@motus.com)
6 //
7 // (C) 2002 Motus Technologies Inc. (http://www.motus.com)
8 //
9
10 using System;
11 using System.Security.Cryptography;
12
13 namespace System.Security.Cryptography {
14
15 // References:
16 // a.   FIPS PUB 46-3: TripleDES
17 //      http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
18 // b.   ANSI X9.52
19 //      not free :-(
20 //      http://webstore.ansi.org/ansidocstore/product.asp?sku=ANSI+X9%2E52%2D1998
21
22 public class TripleDESCryptoServiceProvider : TripleDES {
23
24         public TripleDESCryptoServiceProvider () 
25         {
26         }
27
28         [MonoTODO]
29         public override void GenerateIV () 
30         {
31                 throw new System.NotImplementedException ();
32         }
33         
34         [MonoTODO]
35         public override void GenerateKey () 
36         {
37                 KeyValue = new byte [KeySizeValue / 8];
38         }
39         
40         public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) 
41         {
42                 Key = rgbKey;
43                 IV = rgbIV;
44                 return new TripleDESTransform (this, false, rgbKey, rgbIV);
45         }
46         
47         public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) 
48         {
49                 Key = rgbKey;
50                 IV = rgbIV;
51                 return new TripleDESTransform (this, true, rgbKey, rgbIV);
52         }
53 }
54
55 // TripleDES is just DES-EDE
56 internal class TripleDESTransform : SymmetricTransform {
57
58         // for encryption
59         private DESTransform E1;
60         private DESTransform D2;
61         private DESTransform E3;
62
63         // for decryption
64         private DESTransform D1;
65         private DESTransform E2;
66         private DESTransform D3;
67         
68         public TripleDESTransform (TripleDES algo, bool encryption, byte[] key, byte[] iv) : base (algo, encryption, iv) 
69         {
70                 byte[] key1 = new byte [8];
71                 byte[] key2 = new byte [8];
72                 byte[] key3 = new byte [8];
73                 DES des = DES.Create ();
74                 Array.Copy (key, 0, key1, 0, 8);
75                 Array.Copy (key, 8, key2, 0, 8);
76                 if (key.Length == 16)
77                         Array.Copy (key, 0, key3, 0, 8);
78                 else
79                         Array.Copy (key, 16, key3, 0, 8);
80
81                 // note: some modes (like CFB) requires encryption when decrypting
82                 if ((encryption) || (algo.Mode == CipherMode.CFB)) {
83                         E1 = new DESTransform (des, true, key1, iv);
84                         D2 = new DESTransform (des, false, key2, iv);
85                         E3 = new DESTransform (des, true, key3, iv);
86                 }
87                 else {
88                         D1 = new DESTransform (des, false, key3, iv);
89                         E2 = new DESTransform (des, true, key2, iv);
90                         D3 = new DESTransform (des, false, key1, iv);
91                 }
92         }
93
94         // note: this method is garanteed to be called with a valid blocksize
95         // for both input and output
96         protected override void ECB (byte[] input, byte[] output) 
97         {
98                 byte[] temp = new byte [input.Length];
99                 if (encrypt) {
100                         E1.ProcessBlock (input, output);
101                         D2.ProcessBlock (output, temp);
102                         E3.ProcessBlock (temp, output);
103                 }
104                 else {
105                         D1.ProcessBlock (input, output);
106                         E2.ProcessBlock (output, temp);
107                         D3.ProcessBlock (temp, output);
108                 }
109         }
110 }
111
112 }