(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / corlib / System.Security.Cryptography / RC2CryptoServiceProvider.cs
blob6f214f0d3bc39243840839676cb5ea426fa3bda1
1 //
2 // System.Security.Cryptography.RC2CryptoServiceProvider.cs
3 //
4 // Authors:
5 // Andrew Birkett (andy@nobugs.org)
6 // Sebastien Pouliot (sebastien@ximian.com)
7 //
8 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System;
32 using System.Globalization;
34 using Mono.Security.Cryptography;
36 namespace System.Security.Cryptography {
38 // References:
39 // a. IETF RFC2286: A Description of the RC2(r) Encryption Algorithm
40 // http://www.ietf.org/rfc/rfc2268.txt
42 public sealed class RC2CryptoServiceProvider : RC2 {
44 private bool _useSalt;
46 public RC2CryptoServiceProvider ()
50 public override int EffectiveKeySize {
51 get { return base.EffectiveKeySize; }
52 set {
53 if (value != KeySizeValue) {
54 #if NET_1_1
55 throw new CryptographicUnexpectedOperationException (
56 #else
57 throw new CryptographicException (
58 #endif
59 Locale.GetText ("Effective key size must match key size for compatibility"));
61 base.EffectiveKeySize = value;
65 public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV)
67 Key = rgbKey;
68 IV = rgbIV;
69 return new RC2Transform (this, false);
72 public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV)
74 Key = rgbKey;
75 IV = rgbIV;
76 return new RC2Transform (this, true);
79 public override void GenerateIV ()
81 IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
84 public override void GenerateKey ()
86 KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
88 #if NET_2_0
89 [MonoTODO ("Use salt in algorithm")]
90 public bool UseSalt {
91 get { return _useSalt; }
92 set { _useSalt = value; }
94 #endif
97 internal class RC2Transform : SymmetricTransform {
99 private UInt16 R0, R1, R2, R3; // state
100 private UInt16[] K; // expanded key
101 private int j; // Key indexer
103 public RC2Transform (RC2 rc2Algo, bool encryption) : base (rc2Algo, encryption, rc2Algo.IV)
105 byte[] key = rc2Algo.Key;
106 int t1 = rc2Algo.EffectiveKeySize;
107 // Expand key into a byte array, then convert to word
108 // array since we always access the key in 16bit chunks.
109 byte[] L = new byte [128];
111 int t = key.Length;
112 int t8 = ((t1 + 7) >> 3); // divide by 8
113 int tm = 255 % (2 << (8 + t1 - (t8 << 3) - 1));
115 for (int i=0; i < t; i++)
116 L [i] = key [i];
117 for (int i=t; i < 128; i++)
118 L [i] = (byte) (pitable [(L [i-1] + L [i-t]) & 0xff]);
120 L [128-t8] = pitable [L [128-t8] & tm];
122 for (int i=127-t8; i >= 0; i--)
123 L [i] = pitable [L [i+1] ^ L [i+t8]];
125 K = new UInt16 [64];
126 int pos = 0;
127 for (int i=0; i < 64; i++)
128 K [i] = (UInt16) (L [pos++] + (L [pos++] << 8));
131 protected override void ECB (byte[] input, byte[] output)
133 // unrolled loop, eliminated mul
134 R0 = (UInt16) (input [0] | (input [1] << 8));
135 R1 = (UInt16) (input [2] | (input [3] << 8));
136 R2 = (UInt16) (input [4] | (input [5] << 8));
137 R3 = (UInt16) (input [6] | (input [7] << 8));
139 if (encrypt) {
140 j = 0;
141 // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
142 while (j <= 16) {
143 R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
144 R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
146 R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
147 R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
149 R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
150 R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
152 R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
153 R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
156 // inline Mash(); j == 20
157 R0 += K [R3 & 63];
158 R1 += K [R0 & 63];
159 R2 += K [R1 & 63];
160 R3 += K [R2 & 63];
162 // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix(); Mix();
163 while (j <= 40) {
164 R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
165 R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
167 R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
168 R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
170 R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
171 R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
173 R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
174 R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
177 // inline Mash(); j == 44
178 R0 += K [R3 & 63];
179 R1 += K [R0 & 63];
180 R2 += K [R1 & 63];
181 R3 += K [R2 & 63];
183 // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
184 while (j < 64) {
185 R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
186 R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
188 R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
189 R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
191 R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
192 R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
194 R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
195 R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
198 else {
199 j = 63;
200 // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
201 while (j >= 44) {
202 R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
203 R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
205 R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
206 R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
208 R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
209 R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
211 R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
212 R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
215 // inline RMash();
216 R3 -= K [R2 & 63];
217 R2 -= K [R1 & 63];
218 R1 -= K [R0 & 63];
219 R0 -= K [R3 & 63];
221 // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix(); RMix();
222 while (j >= 20) {
223 R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
224 R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
226 R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
227 R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
229 R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
230 R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
232 R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
233 R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
236 // inline RMash();
237 R3 -= K [R2 & 63];
238 R2 -= K [R1 & 63];
239 R1 -= K [R0 & 63];
240 R0 -= K [R3 & 63];
242 // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
243 while (j >= 0) {
244 R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
245 R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
247 R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
248 R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
250 R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
251 R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
253 R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
254 R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
258 // unrolled loop
259 output[0] = (byte) R0;
260 output[1] = (byte) (R0 >> 8);
261 output[2] = (byte) R1;
262 output[3] = (byte) (R1 >> 8);
263 output[4] = (byte) R2;
264 output[5] = (byte) (R2 >> 8);
265 output[6] = (byte) R3;
266 output[7] = (byte) (R3 >> 8);
269 static readonly byte[] pitable = {
270 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed,
271 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
272 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
273 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
274 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13,
275 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
276 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b,
277 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
278 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
279 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
280 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1,
281 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
282 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57,
283 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
284 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
285 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
286 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7,
287 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
288 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74,
289 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
290 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
291 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
292 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a,
293 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
294 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae,
295 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
296 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
297 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
298 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0,
299 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
300 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77,
301 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad