Wed Nov 14 16:30:27 CET 2001 Paolo Molaro <lupus@ximian.com>
[mono.git] / mcs / class / corlib / System.Security.Cryptography / SymmetricAlgorithm.cs
1 //\r
2 // System.Security.Cryptography SymmetricAlgorithm Class implementation\r
3 //\r
4 // Authors:\r
5 //   Thomas Neidhart (tome@sbox.tugraz.at)\r
6 //\r
7 \r
8 using System;\r
9 \r
10 namespace System.Security.Cryptography {\r
11         \r
12         /// <summary>\r
13         /// Abstract base class for all cryptographic symmetric algorithms.\r
14         /// Available algorithms include:\r
15         /// DES, RC2, Rijndael, TripleDES\r
16         /// </summary>\r
17         public abstract class SymmetricAlgorithm {\r
18                 protected int BlockSizeValue; // The block size of the cryptographic operation in bits. \r
19                 protected int FeedbackSizeValue; // The feedback size of the cryptographic operation in bits. \r
20                 protected byte[] IVValue; // The initialization vector ( IV) for the symmetric algorithm. \r
21                 protected int KeySizeValue; // The size of the secret key used by the symmetric algorithm in bits. \r
22                 protected byte[] KeyValue; // The secret key for the symmetric algorithm. \r
23                 protected KeySizes[] LegalBlockSizesValue; // Specifies the block sizes that are supported by the symmetric algorithm. \r
24                 protected KeySizes[] LegalKeySizesValue; // Specifies the key sizes that are supported by the symmetric algorithm. \r
25                 protected CipherMode ModeValue; // Represents the cipher mode used in the symmetric algorithm. \r
26                 protected PaddingMode PaddingValue; // Represents the padding mode used in the symmetric algorithm. \r
27 \r
28                 /// <summary>\r
29                 /// Called from constructor of derived class.\r
30                 /// </summary>\r
31                 public SymmetricAlgorithm () {\r
32                   throw new CryptographicException();\r
33                 }\r
34                 \r
35                 /// <summary>\r
36                 /// Called from constructor of derived class.\r
37                 /// </summary>\r
38                 ~SymmetricAlgorithm () {\r
39                         if (KeyValue != null) {\r
40                                 Array.Clear(KeyValue, 0, KeyValue.Length);\r
41                                 KeyValue = null;\r
42                         }\r
43                 }\r
44 \r
45                 /// <summary>\r
46                 /// Gets or sets the actual BlockSize\r
47                 /// </summary>\r
48                 public virtual int BlockSize {\r
49                         get {\r
50                                 return this.BlockSizeValue;\r
51                         }\r
52                         set {\r
53                                 if (IsLegalKeySize(this.LegalBlockSizesValue, value))\r
54                                         this.BlockSizeValue = value;\r
55                                 else\r
56                                         throw new CryptographicException("block size not supported by algorithm");\r
57                         }\r
58                 }\r
59 \r
60                 /// <summary>\r
61                 /// Gets or sets the actual FeedbackSize\r
62                 /// </summary>\r
63                 public virtual int FeedbackSize {\r
64                         get {\r
65                                 return this.FeedbackSizeValue;\r
66                         }\r
67                         set {\r
68                                 if (value > this.BlockSizeValue)\r
69                                         throw new CryptographicException("feedback size larger than block size");\r
70                                 else\r
71                                         this.FeedbackSizeValue = value;\r
72                         }\r
73                 }\r
74                 \r
75                 /// <summary>\r
76                 /// Gets or sets the actual Initial Vector\r
77                 /// </summary>\r
78                 public virtual byte[] IV {\r
79                         get {\r
80                                 if (this.IVValue == null)\r
81                                         GenerateIV();\r
82 \r
83                                 return this.IVValue;\r
84                         }\r
85                         set {\r
86                                 if (value == null)\r
87                                         throw new ArgumentNullException("tried setting initial vector to null");\r
88                                         \r
89                                 // FIXME: dont know if to compare with block or key size        \r
90                                 if (value.Length != this.KeySizeValue)\r
91                                         throw new CryptographicException("tried setting initial vector with illegal size");\r
92                                 \r
93                                 this.IVValue = new byte [value.Length];\r
94                                 System.Array.Copy (value, 0, this.IVValue, 0, value.Length);\r
95                         }\r
96                 }\r
97 \r
98                 /// <summary>\r
99                 /// Gets or sets the actual key\r
100                 /// </summary>\r
101                 public virtual byte[] Key {\r
102                         get {\r
103                                 if (this.KeyValue == null)\r
104                                         GenerateKey();\r
105 \r
106                                 return this.KeyValue;\r
107                         }\r
108                         set {\r
109                                 if (value == null)\r
110                                         throw new ArgumentNullException("tried setting key to null");\r
111 \r
112                                 if (!IsLegalKeySize(this.LegalKeySizesValue, value.Length))\r
113                                         throw new CryptographicException("key size not supported by algorithm");\r
114 \r
115                                 this.KeySizeValue = value.Length;\r
116                                 this.KeyValue = new byte [this.KeySizeValue];\r
117                                 System.Array.Copy (value, 0, this.KeyValue, 0, this.KeySizeValue);\r
118                         }\r
119                 }\r
120                 \r
121                 /// <summary>\r
122                 /// Gets or sets the actual key size\r
123                 /// </summary>\r
124                 public virtual int KeySize {\r
125                         get {\r
126                                 return this.KeySizeValue;\r
127                         }\r
128                         set {\r
129                                 if (!IsLegalKeySize(this.LegalKeySizesValue, value))\r
130                                         throw new CryptographicException("key size not supported by algorithm");\r
131                                 \r
132                                 this.KeyValue = null;\r
133                                 this.KeySizeValue = value;\r
134                         }\r
135                 }\r
136 \r
137                 /// <summary>\r
138                 /// Gets all legal block sizes\r
139                 /// </summary>\r
140                 public virtual KeySizes[] LegalBlockSizes {\r
141                         get {\r
142                                 return this.LegalBlockSizesValue;\r
143                         }\r
144                 }\r
145 \r
146                 /// <summary>\r
147                 /// Gets all legal key sizes\r
148                 /// </summary>\r
149                 public virtual KeySizes[] LegalKeySizes {\r
150                         get {\r
151                                 return this.LegalKeySizesValue;\r
152                         }\r
153                 }\r
154 \r
155                 /// <summary>\r
156                 /// Gets or sets the actual cipher mode\r
157                 /// </summary>\r
158                 public virtual CipherMode Mode {\r
159                         get {\r
160                                 return this.ModeValue;\r
161                         }\r
162                         set {\r
163                                 if (Enum.IsDefined(ModeValue.GetType(), value))\r
164                                         this.ModeValue = value;\r
165                                 else\r
166                                         throw new CryptographicException("padding mode not available");\r
167                         }\r
168                 }\r
169 \r
170                 /// <summary>\r
171                 /// Gets or sets the actual padding\r
172                 /// </summary>\r
173                 public virtual PaddingMode Padding {\r
174                         get {\r
175                                 return this.PaddingValue;\r
176                         }\r
177                         set {\r
178                                 if (Enum.IsDefined(PaddingValue.GetType(), value))\r
179                                         this.PaddingValue = value;\r
180                                 else\r
181                                         throw new CryptographicException("padding mode not available");\r
182                         }\r
183                 }\r
184 \r
185                 /// <summary>\r
186                 /// Gets an Decryptor transform object to work with a CryptoStream\r
187                 /// </summary>\r
188                 public virtual ICryptoTransform CreateDecryptor() {\r
189                         return CreateDecryptor(Key, IV);\r
190                 }\r
191 \r
192                 /// <summary>\r
193                 /// Gets an Decryptor transform object to work with a CryptoStream\r
194                 /// </summary>\r
195                 public abstract ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV);\r
196 \r
197                 /// <summary>\r
198                 /// Gets an Encryptor transform object to work with a CryptoStream\r
199                 /// </summary>\r
200                 public virtual ICryptoTransform CreateEncryptor() {\r
201                         return CreateEncryptor(Key, IV);\r
202                 }\r
203 \r
204                 /// <summary>\r
205                 /// Gets an Encryptor transform object to work with a CryptoStream\r
206                 /// </summary>\r
207                 public abstract ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV);\r
208 \r
209                 /// <summary>\r
210                 /// used to generate an inital vector if none is specified\r
211                 /// </summary>\r
212                 public abstract void GenerateIV();\r
213 \r
214                 /// </summary>\r
215                 /// used to generate a random key if none is specified\r
216                 /// </summary>\r
217                 public abstract void GenerateKey();\r
218 \r
219                 internal bool IsLegalKeySize(KeySizes[] LegalKeys, int Size) {\r
220                         foreach (KeySizes LegalKeySize in LegalKeys) {\r
221                                 for (int i=LegalKeySize.MinSize; i<=LegalKeySize.MaxSize; i+=LegalKeySize.SkipSize) {\r
222                                         if (i == Size)\r
223                                                 return true;\r
224                                 }\r
225                         }\r
226                         return false;\r
227                 }\r
228                 \r
229                 /// <summary>\r
230                 /// Checks wether the given keyLength is valid for the current algorithm\r
231                 /// </summary>\r
232                 /// <param name="bitLength">the given keyLength</param>\r
233                 public bool ValidKeySize(int bitLength) {\r
234                         return IsLegalKeySize(LegalKeySizesValue, bitLength);\r
235                 }\r
236                 \r
237                 /// <summary>\r
238                 /// Creates the default implementation of the default symmetric algorithm (RC2).\r
239                 /// </summary>\r
240                 public static SymmetricAlgorithm Create () {\r
241                         return Rijndael.Create();\r
242                 }\r
243         \r
244                 /// <summary>\r
245                 /// Creates a specific implementation of the given symmetric algorithm.\r
246                 /// </summary>\r
247                 /// <param name="algName">the given algorithm</param>\r
248                 public static SymmetricAlgorithm Create (string algName) {\r
249                         // TODO: Use Reflection to create a new algorithm instance\r
250                         return null;\r
251                 }\r
252         }\r
253 }\r
254 \r