2004-03-09 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / corlib / System.Security.Cryptography / MACTripleDES.cs
1 //
2 // MACTripleDES.cs: Handles MAC with TripleDES
3 //
4 // Author:
5 //      Sebastien Pouliot (spouliot@motus.com)
6 //
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 //
9
10 using System;
11
12 using Mono.Security.Cryptography;
13
14 namespace System.Security.Cryptography {
15
16         // References:
17         // a.   FIPS PUB 81: DES MODES OF OPERATION 
18         //      MAC: Appendix F (MACDES not MACTripleDES but close enough ;-)
19         //      http://www.itl.nist.gov/fipspubs/fip81.htm
20         
21         // LAMESPEC: MACTripleDES == MAC-CBC using TripleDES (not MAC-CFB).
22         public class MACTripleDES: KeyedHashAlgorithm {
23         
24                 private TripleDES tdes;
25                 private MACAlgorithm mac;
26                 private bool m_disposed;
27         
28                 public MACTripleDES ()
29                 {
30                         Setup ("TripleDES", null);
31                 }
32         
33                 public MACTripleDES (byte[] rgbKey)
34                 {
35                         if (rgbKey == null)
36                                 throw new ArgumentNullException ("rgbKey");
37                         Setup ("TripleDES", rgbKey);
38                 }
39         
40                 public MACTripleDES (string strTripleDES, byte[] rgbKey) 
41                 {
42                         if (rgbKey == null)
43                                 throw new ArgumentNullException ("rgbKey");
44                         if (strTripleDES == null)
45                                 Setup ("TripleDES", rgbKey);
46                         else
47                                 Setup (strTripleDES, rgbKey);
48                 }
49         
50                 private void Setup (string strTripleDES, byte[] rgbKey) 
51                 {
52                         tdes = TripleDES.Create (strTripleDES);
53                         // if rgbKey is null we keep the randomly generated key
54                         if (rgbKey != null) {
55                                 // this way we get the TripleDES key validation (like weak
56                                 // and semi-weak keys)
57                                 tdes.Key = rgbKey;
58                         }
59                         HashSizeValue = tdes.BlockSize;
60                         // we use Key property to get the additional validations 
61                         // (from KeyedHashAlgorithm ancestor)
62                         Key = tdes.Key;
63                         mac = new MACAlgorithm (tdes);
64                         m_disposed = false;
65                 }
66         
67                 ~MACTripleDES () 
68                 {
69                         Dispose (false);
70                 }
71         
72                 protected override void Dispose (bool disposing) 
73                 {
74                         if (!m_disposed) {
75                                 // note: we ALWAYS zeroize keys (disposing or not)
76         
77                                 // clear our copy of the secret key
78                                 if (KeyValue != null)
79                                         Array.Clear (KeyValue, 0, KeyValue.Length);
80                                 // clear the secret key (inside TripleDES)
81                                 if (tdes != null)
82                                         tdes.Clear ();
83         
84                                 if (disposing) {
85                                         // disposed managed stuff
86                                         KeyValue = null;
87                                         tdes = null;
88                                 }
89                                 // ancestor
90                                 base.Dispose (disposing);
91                                 m_disposed = true;
92                         }
93                 }
94         
95                 public override void Initialize () 
96                 {
97                         if (m_disposed)
98                                 throw new ObjectDisposedException ("MACTripleDES");
99                         State = 0;
100                         mac.Initialize (KeyValue);
101                 }
102         
103                 protected override void HashCore (byte[] rgb, int ib, int cb) 
104                 {
105                         if (m_disposed)
106                                 throw new ObjectDisposedException ("MACTripleDES");
107                         if (State == 0) {
108                                 Initialize ();
109                                 State = 1;
110                         }
111                         mac.Core (rgb, ib, cb);
112                 }
113         
114                 protected override byte[] HashFinal () 
115                 {
116                         if (m_disposed)
117                                 throw new ObjectDisposedException ("MACTripleDES");
118                         State = 0;
119                         return mac.Final ();
120                 }
121         }
122 }