[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / class / corlib / System.Security.Cryptography / DESCryptoServiceProvider.cs
blob00248cd8c3eb8812a001aeeb63a5d0ba79257189
1 //
2 // System.Security.Cryptography.DESCryptoServiceProvider
3 //
4 // Authors:
5 // Sergey Chaban (serge@wildwestsoftware.com)
6 // Sebastien Pouliot (sebastien@ximian.com)
7 //
8 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
9 // Copyright (C) 2004-2005 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.Runtime.InteropServices;
32 using Mono.Security.Cryptography;
34 namespace System.Security.Cryptography {
36 // References:
37 // a. FIPS PUB 46-3: Data Encryption Standard
38 // http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
40 internal class DESTransform : SymmetricTransform {
42 internal static readonly int KEY_BIT_SIZE = 64;
43 internal static readonly int KEY_BYTE_SIZE = KEY_BIT_SIZE / 8;
44 internal static readonly int BLOCK_BIT_SIZE = 64;
45 internal static readonly int BLOCK_BYTE_SIZE = BLOCK_BIT_SIZE / 8;
47 private byte[] keySchedule;
48 private byte[] byteBuff;
49 private uint[] dwordBuff;
50 /*
51 // S-boxes from FIPS 46-3, Appendix 1, page 17
52 private static readonly byte [] sBoxes = {
53 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
54 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
55 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
56 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
58 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
59 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
60 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
61 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
63 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
64 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
65 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
66 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
68 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
69 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
70 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
71 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
73 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
74 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
75 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
76 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
78 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
79 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
80 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
81 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
83 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
84 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
85 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
86 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
88 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
89 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
90 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
91 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
94 // P table from page 15, also in Appendix 1, page 18
95 private static readonly byte [] pTab = {
96 16-1, 7-1, 20-1, 21-1,
97 29-1, 12-1, 28-1, 17-1,
98 1-1, 15-1, 23-1, 26-1,
99 5-1, 18-1, 31-1, 10-1,
100 2-1, 8-1, 24-1, 14-1,
101 32-1, 27-1, 3-1, 9-1,
102 19-1, 13-1, 30-1, 6-1,
103 22-1, 11-1, 4-1, 25-1
106 // pre-computed result of sBoxes (using pTab)
107 private static readonly uint[] spBoxes = {
108 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000,
109 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002,
110 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
111 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000,
112 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200,
113 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
114 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200,
115 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002,
116 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010,
117 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010,
118 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
119 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010,
120 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000,
121 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
122 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010,
123 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000,
124 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100,
125 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104,
126 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
127 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000,
128 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000,
129 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
130 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004,
131 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100,
132 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000,
133 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000,
134 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
135 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040,
136 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000,
137 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
138 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040,
139 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040,
140 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000,
141 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000,
142 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
143 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080,
144 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080,
145 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
146 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000,
147 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080,
148 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000,
149 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008,
150 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
151 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000,
152 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008,
153 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
154 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008,
155 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008,
156 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400,
157 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401,
158 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
159 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400,
160 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001,
161 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
162 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401,
163 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001,
164 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000,
165 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020,
166 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
167 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000,
168 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820,
169 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
170 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000,
171 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800
174 // Permuted choice 1 table, PC-1, page 19
175 // Translated to zero-based format.
176 private static readonly byte [] PC1 = {
177 57-1, 49-1, 41-1, 33-1, 25-1, 17-1, 9-1,
178 1-1, 58-1, 50-1, 42-1, 34-1, 26-1, 18-1,
179 10-1, 2-1, 59-1, 51-1, 43-1, 35-1, 27-1,
180 19-1, 11-1, 3-1, 60-1, 52-1, 44-1, 36-1,
182 63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1,
183 7-1, 62-1, 54-1, 46-1, 38-1, 30-1, 22-1,
184 14-1, 6-1, 61-1, 53-1, 45-1, 37-1, 29-1,
185 21-1, 13-1, 5-1, 28-1, 20-1, 12-1, 4-1
189 private static readonly byte [] leftRot = {
190 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
193 // pre-computed result of leftRot
194 private static readonly byte[] leftRotTotal = { 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x0F, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1C };
196 // Permuted choice 2 table, PC-2, page 21
197 // Translated to zero-based format.
198 private static readonly byte [] PC2 = {
199 14-1, 17-1, 11-1, 24-1, 1-1, 5-1,
200 3-1, 28-1, 15-1, 6-1, 21-1, 10-1,
201 23-1, 19-1, 12-1, 4-1, 26-1, 8-1,
202 16-1, 7-1, 27-1, 20-1, 13-1, 2-1,
203 41-1, 52-1, 31-1, 37-1, 47-1, 55-1,
204 30-1, 40-1, 51-1, 45-1, 33-1, 48-1,
205 44-1, 49-1, 39-1, 56-1, 34-1, 53-1,
206 46-1, 42-1, 50-1, 36-1, 29-1, 32-1
210 // Initial permutation IP, page 10.
211 // Transposed to 0-based format.
212 private static readonly byte [] ipBits = {
213 58-1, 50-1, 42-1, 34-1, 26-1, 18-1, 10-1, 2-1,
214 60-1, 52-1, 44-1, 36-1, 28-1, 20-1, 12-1, 4-1,
215 62-1, 54-1, 46-1, 38-1, 30-1, 22-1, 14-1, 6-1,
216 64-1, 56-1, 48-1, 40-1, 32-1, 24-1, 16-1, 8-1,
217 57-1, 49-1, 41-1, 33-1, 25-1, 17-1, 9-1, 1-1,
218 59-1, 51-1, 43-1, 35-1, 27-1, 19-1, 11-1, 3-1,
219 61-1, 53-1, 45-1, 37-1, 29-1, 21-1, 13-1, 5-1,
220 63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1, 7-1
224 // Final permutation FP = IP^(-1), page 10.
225 // Transposed to 0-based format.
226 private static readonly byte [] fpBits = {
227 40-1, 8-1, 48-1, 16-1, 56-1, 24-1, 64-1, 32-1,
228 39-1, 7-1, 47-1, 15-1, 55-1, 23-1, 63-1, 31-1,
229 38-1, 6-1, 46-1, 14-1, 54-1, 22-1, 62-1, 30-1,
230 37-1, 5-1, 45-1, 13-1, 53-1, 21-1, 61-1, 29-1,
231 36-1, 4-1, 44-1, 12-1, 52-1, 20-1, 60-1, 28-1,
232 35-1, 3-1, 43-1, 11-1, 51-1, 19-1, 59-1, 27-1,
233 34-1, 2-1, 42-1, 10-1, 50-1, 18-1, 58-1, 26-1,
234 33-1, 1-1, 41-1, 9-1, 49-1, 17-1, 57-1, 25-1
237 internal static readonly uint[] ipTab = {
238 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000, 0x00000100, 0x00000100, 0x00000100,
239 0x00000001, 0x00000000, 0x00000101, 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00000100,
240 0x00000000, 0x00000001, 0x00000100, 0x00000001, 0x00000000, 0x00000101, 0x00000100, 0x00000101,
241 0x00000001, 0x00000001, 0x00000101, 0x00000001, 0x00000001, 0x00000101, 0x00000101, 0x00000101,
242 0x00000000, 0x00000000, 0x01000000, 0x00000000, 0x00000000, 0x01000000, 0x01000000, 0x01000000,
243 0x00010000, 0x00000000, 0x01010000, 0x00000000, 0x00010000, 0x01000000, 0x01010000, 0x01000000,
244 0x00000000, 0x00010000, 0x01000000, 0x00010000, 0x00000000, 0x01010000, 0x01000000, 0x01010000,
245 0x00010000, 0x00010000, 0x01010000, 0x00010000, 0x00010000, 0x01010000, 0x01010000, 0x01010000,
246 0x00000000, 0x00000000, 0x00000200, 0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000200,
247 0x00000002, 0x00000000, 0x00000202, 0x00000000, 0x00000002, 0x00000200, 0x00000202, 0x00000200,
248 0x00000000, 0x00000002, 0x00000200, 0x00000002, 0x00000000, 0x00000202, 0x00000200, 0x00000202,
249 0x00000002, 0x00000002, 0x00000202, 0x00000002, 0x00000002, 0x00000202, 0x00000202, 0x00000202,
250 0x00000000, 0x00000000, 0x02000000, 0x00000000, 0x00000000, 0x02000000, 0x02000000, 0x02000000,
251 0x00020000, 0x00000000, 0x02020000, 0x00000000, 0x00020000, 0x02000000, 0x02020000, 0x02000000,
252 0x00000000, 0x00020000, 0x02000000, 0x00020000, 0x00000000, 0x02020000, 0x02000000, 0x02020000,
253 0x00020000, 0x00020000, 0x02020000, 0x00020000, 0x00020000, 0x02020000, 0x02020000, 0x02020000,
254 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000400,
255 0x00000004, 0x00000000, 0x00000404, 0x00000000, 0x00000004, 0x00000400, 0x00000404, 0x00000400,
256 0x00000000, 0x00000004, 0x00000400, 0x00000004, 0x00000000, 0x00000404, 0x00000400, 0x00000404,
257 0x00000004, 0x00000004, 0x00000404, 0x00000004, 0x00000004, 0x00000404, 0x00000404, 0x00000404,
258 0x00000000, 0x00000000, 0x04000000, 0x00000000, 0x00000000, 0x04000000, 0x04000000, 0x04000000,
259 0x00040000, 0x00000000, 0x04040000, 0x00000000, 0x00040000, 0x04000000, 0x04040000, 0x04000000,
260 0x00000000, 0x00040000, 0x04000000, 0x00040000, 0x00000000, 0x04040000, 0x04000000, 0x04040000,
261 0x00040000, 0x00040000, 0x04040000, 0x00040000, 0x00040000, 0x04040000, 0x04040000, 0x04040000,
262 0x00000000, 0x00000000, 0x00000800, 0x00000000, 0x00000000, 0x00000800, 0x00000800, 0x00000800,
263 0x00000008, 0x00000000, 0x00000808, 0x00000000, 0x00000008, 0x00000800, 0x00000808, 0x00000800,
264 0x00000000, 0x00000008, 0x00000800, 0x00000008, 0x00000000, 0x00000808, 0x00000800, 0x00000808,
265 0x00000008, 0x00000008, 0x00000808, 0x00000008, 0x00000008, 0x00000808, 0x00000808, 0x00000808,
266 0x00000000, 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x08000000, 0x08000000, 0x08000000,
267 0x00080000, 0x00000000, 0x08080000, 0x00000000, 0x00080000, 0x08000000, 0x08080000, 0x08000000,
268 0x00000000, 0x00080000, 0x08000000, 0x00080000, 0x00000000, 0x08080000, 0x08000000, 0x08080000,
269 0x00080000, 0x00080000, 0x08080000, 0x00080000, 0x00080000, 0x08080000, 0x08080000, 0x08080000,
270 0x00000000, 0x00000000, 0x00001000, 0x00000000, 0x00000000, 0x00001000, 0x00001000, 0x00001000,
271 0x00000010, 0x00000000, 0x00001010, 0x00000000, 0x00000010, 0x00001000, 0x00001010, 0x00001000,
272 0x00000000, 0x00000010, 0x00001000, 0x00000010, 0x00000000, 0x00001010, 0x00001000, 0x00001010,
273 0x00000010, 0x00000010, 0x00001010, 0x00000010, 0x00000010, 0x00001010, 0x00001010, 0x00001010,
274 0x00000000, 0x00000000, 0x10000000, 0x00000000, 0x00000000, 0x10000000, 0x10000000, 0x10000000,
275 0x00100000, 0x00000000, 0x10100000, 0x00000000, 0x00100000, 0x10000000, 0x10100000, 0x10000000,
276 0x00000000, 0x00100000, 0x10000000, 0x00100000, 0x00000000, 0x10100000, 0x10000000, 0x10100000,
277 0x00100000, 0x00100000, 0x10100000, 0x00100000, 0x00100000, 0x10100000, 0x10100000, 0x10100000,
278 0x00000000, 0x00000000, 0x00002000, 0x00000000, 0x00000000, 0x00002000, 0x00002000, 0x00002000,
279 0x00000020, 0x00000000, 0x00002020, 0x00000000, 0x00000020, 0x00002000, 0x00002020, 0x00002000,
280 0x00000000, 0x00000020, 0x00002000, 0x00000020, 0x00000000, 0x00002020, 0x00002000, 0x00002020,
281 0x00000020, 0x00000020, 0x00002020, 0x00000020, 0x00000020, 0x00002020, 0x00002020, 0x00002020,
282 0x00000000, 0x00000000, 0x20000000, 0x00000000, 0x00000000, 0x20000000, 0x20000000, 0x20000000,
283 0x00200000, 0x00000000, 0x20200000, 0x00000000, 0x00200000, 0x20000000, 0x20200000, 0x20000000,
284 0x00000000, 0x00200000, 0x20000000, 0x00200000, 0x00000000, 0x20200000, 0x20000000, 0x20200000,
285 0x00200000, 0x00200000, 0x20200000, 0x00200000, 0x00200000, 0x20200000, 0x20200000, 0x20200000,
286 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0x00000000, 0x00004000, 0x00004000, 0x00004000,
287 0x00000040, 0x00000000, 0x00004040, 0x00000000, 0x00000040, 0x00004000, 0x00004040, 0x00004000,
288 0x00000000, 0x00000040, 0x00004000, 0x00000040, 0x00000000, 0x00004040, 0x00004000, 0x00004040,
289 0x00000040, 0x00000040, 0x00004040, 0x00000040, 0x00000040, 0x00004040, 0x00004040, 0x00004040,
290 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000, 0x40000000, 0x40000000, 0x40000000,
291 0x00400000, 0x00000000, 0x40400000, 0x00000000, 0x00400000, 0x40000000, 0x40400000, 0x40000000,
292 0x00000000, 0x00400000, 0x40000000, 0x00400000, 0x00000000, 0x40400000, 0x40000000, 0x40400000,
293 0x00400000, 0x00400000, 0x40400000, 0x00400000, 0x00400000, 0x40400000, 0x40400000, 0x40400000,
294 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00008000, 0x00008000, 0x00008000,
295 0x00000080, 0x00000000, 0x00008080, 0x00000000, 0x00000080, 0x00008000, 0x00008080, 0x00008000,
296 0x00000000, 0x00000080, 0x00008000, 0x00000080, 0x00000000, 0x00008080, 0x00008000, 0x00008080,
297 0x00000080, 0x00000080, 0x00008080, 0x00000080, 0x00000080, 0x00008080, 0x00008080, 0x00008080,
298 0x00000000, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0x80000000, 0x80000000, 0x80000000,
299 0x00800000, 0x00000000, 0x80800000, 0x00000000, 0x00800000, 0x80000000, 0x80800000, 0x80000000,
300 0x00000000, 0x00800000, 0x80000000, 0x00800000, 0x00000000, 0x80800000, 0x80000000, 0x80800000,
301 0x00800000, 0x00800000, 0x80800000, 0x00800000, 0x00800000, 0x80800000, 0x80800000, 0x80800000
304 internal static readonly uint[] fpTab = {
305 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00004000, 0x00000000, 0x00004040,
306 0x00000000, 0x00400000, 0x00000000, 0x00400040, 0x00000000, 0x00404000, 0x00000000, 0x00404040,
307 0x00000000, 0x40000000, 0x00000000, 0x40000040, 0x00000000, 0x40004000, 0x00000000, 0x40004040,
308 0x00000000, 0x40400000, 0x00000000, 0x40400040, 0x00000000, 0x40404000, 0x00000000, 0x40404040,
309 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00004000, 0x00000000, 0x00004040, 0x00000000,
310 0x00400000, 0x00000000, 0x00400040, 0x00000000, 0x00404000, 0x00000000, 0x00404040, 0x00000000,
311 0x40000000, 0x00000000, 0x40000040, 0x00000000, 0x40004000, 0x00000000, 0x40004040, 0x00000000,
312 0x40400000, 0x00000000, 0x40400040, 0x00000000, 0x40404000, 0x00000000, 0x40404040, 0x00000000,
313 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00001000, 0x00000000, 0x00001010,
314 0x00000000, 0x00100000, 0x00000000, 0x00100010, 0x00000000, 0x00101000, 0x00000000, 0x00101010,
315 0x00000000, 0x10000000, 0x00000000, 0x10000010, 0x00000000, 0x10001000, 0x00000000, 0x10001010,
316 0x00000000, 0x10100000, 0x00000000, 0x10100010, 0x00000000, 0x10101000, 0x00000000, 0x10101010,
317 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00001000, 0x00000000, 0x00001010, 0x00000000,
318 0x00100000, 0x00000000, 0x00100010, 0x00000000, 0x00101000, 0x00000000, 0x00101010, 0x00000000,
319 0x10000000, 0x00000000, 0x10000010, 0x00000000, 0x10001000, 0x00000000, 0x10001010, 0x00000000,
320 0x10100000, 0x00000000, 0x10100010, 0x00000000, 0x10101000, 0x00000000, 0x10101010, 0x00000000,
321 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000400, 0x00000000, 0x00000404,
322 0x00000000, 0x00040000, 0x00000000, 0x00040004, 0x00000000, 0x00040400, 0x00000000, 0x00040404,
323 0x00000000, 0x04000000, 0x00000000, 0x04000004, 0x00000000, 0x04000400, 0x00000000, 0x04000404,
324 0x00000000, 0x04040000, 0x00000000, 0x04040004, 0x00000000, 0x04040400, 0x00000000, 0x04040404,
325 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000400, 0x00000000, 0x00000404, 0x00000000,
326 0x00040000, 0x00000000, 0x00040004, 0x00000000, 0x00040400, 0x00000000, 0x00040404, 0x00000000,
327 0x04000000, 0x00000000, 0x04000004, 0x00000000, 0x04000400, 0x00000000, 0x04000404, 0x00000000,
328 0x04040000, 0x00000000, 0x04040004, 0x00000000, 0x04040400, 0x00000000, 0x04040404, 0x00000000,
329 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000100, 0x00000000, 0x00000101,
330 0x00000000, 0x00010000, 0x00000000, 0x00010001, 0x00000000, 0x00010100, 0x00000000, 0x00010101,
331 0x00000000, 0x01000000, 0x00000000, 0x01000001, 0x00000000, 0x01000100, 0x00000000, 0x01000101,
332 0x00000000, 0x01010000, 0x00000000, 0x01010001, 0x00000000, 0x01010100, 0x00000000, 0x01010101,
333 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000100, 0x00000000, 0x00000101, 0x00000000,
334 0x00010000, 0x00000000, 0x00010001, 0x00000000, 0x00010100, 0x00000000, 0x00010101, 0x00000000,
335 0x01000000, 0x00000000, 0x01000001, 0x00000000, 0x01000100, 0x00000000, 0x01000101, 0x00000000,
336 0x01010000, 0x00000000, 0x01010001, 0x00000000, 0x01010100, 0x00000000, 0x01010101, 0x00000000,
337 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x00000000, 0x00008000, 0x00000000, 0x00008080,
338 0x00000000, 0x00800000, 0x00000000, 0x00800080, 0x00000000, 0x00808000, 0x00000000, 0x00808080,
339 0x00000000, 0x80000000, 0x00000000, 0x80000080, 0x00000000, 0x80008000, 0x00000000, 0x80008080,
340 0x00000000, 0x80800000, 0x00000000, 0x80800080, 0x00000000, 0x80808000, 0x00000000, 0x80808080,
341 0x00000000, 0x00000000, 0x00000080, 0x00000000, 0x00008000, 0x00000000, 0x00008080, 0x00000000,
342 0x00800000, 0x00000000, 0x00800080, 0x00000000, 0x00808000, 0x00000000, 0x00808080, 0x00000000,
343 0x80000000, 0x00000000, 0x80000080, 0x00000000, 0x80008000, 0x00000000, 0x80008080, 0x00000000,
344 0x80800000, 0x00000000, 0x80800080, 0x00000000, 0x80808000, 0x00000000, 0x80808080, 0x00000000,
345 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0x00000000, 0x00002000, 0x00000000, 0x00002020,
346 0x00000000, 0x00200000, 0x00000000, 0x00200020, 0x00000000, 0x00202000, 0x00000000, 0x00202020,
347 0x00000000, 0x20000000, 0x00000000, 0x20000020, 0x00000000, 0x20002000, 0x00000000, 0x20002020,
348 0x00000000, 0x20200000, 0x00000000, 0x20200020, 0x00000000, 0x20202000, 0x00000000, 0x20202020,
349 0x00000000, 0x00000000, 0x00000020, 0x00000000, 0x00002000, 0x00000000, 0x00002020, 0x00000000,
350 0x00200000, 0x00000000, 0x00200020, 0x00000000, 0x00202000, 0x00000000, 0x00202020, 0x00000000,
351 0x20000000, 0x00000000, 0x20000020, 0x00000000, 0x20002000, 0x00000000, 0x20002020, 0x00000000,
352 0x20200000, 0x00000000, 0x20200020, 0x00000000, 0x20202000, 0x00000000, 0x20202020, 0x00000000,
353 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000000, 0x00000800, 0x00000000, 0x00000808,
354 0x00000000, 0x00080000, 0x00000000, 0x00080008, 0x00000000, 0x00080800, 0x00000000, 0x00080808,
355 0x00000000, 0x08000000, 0x00000000, 0x08000008, 0x00000000, 0x08000800, 0x00000000, 0x08000808,
356 0x00000000, 0x08080000, 0x00000000, 0x08080008, 0x00000000, 0x08080800, 0x00000000, 0x08080808,
357 0x00000000, 0x00000000, 0x00000008, 0x00000000, 0x00000800, 0x00000000, 0x00000808, 0x00000000,
358 0x00080000, 0x00000000, 0x00080008, 0x00000000, 0x00080800, 0x00000000, 0x00080808, 0x00000000,
359 0x08000000, 0x00000000, 0x08000008, 0x00000000, 0x08000800, 0x00000000, 0x08000808, 0x00000000,
360 0x08080000, 0x00000000, 0x08080008, 0x00000000, 0x08080800, 0x00000000, 0x08080808, 0x00000000,
361 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000200, 0x00000000, 0x00000202,
362 0x00000000, 0x00020000, 0x00000000, 0x00020002, 0x00000000, 0x00020200, 0x00000000, 0x00020202,
363 0x00000000, 0x02000000, 0x00000000, 0x02000002, 0x00000000, 0x02000200, 0x00000000, 0x02000202,
364 0x00000000, 0x02020000, 0x00000000, 0x02020002, 0x00000000, 0x02020200, 0x00000000, 0x02020202,
365 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000200, 0x00000000, 0x00000202, 0x00000000,
366 0x00020000, 0x00000000, 0x00020002, 0x00000000, 0x00020200, 0x00000000, 0x00020202, 0x00000000,
367 0x02000000, 0x00000000, 0x02000002, 0x00000000, 0x02000200, 0x00000000, 0x02000202, 0x00000000,
368 0x02020000, 0x00000000, 0x02020002, 0x00000000, 0x02020200, 0x00000000, 0x02020202, 0x00000000
371 /* static DESTransform ()
373 spBoxes = new uint [64 * 8];
375 int [] pBox = new int [32];
377 for (int p = 0; p < 32; p++) {
378 for (int i = 0; i < 32; i++) {
379 if (p == pTab [i]) {
380 pBox [p] = i;
381 break;
386 for (int s = 0; s < 8; s++) { // for each S-box
387 int sOff = s << 6;
389 for (int i = 0; i < 64; i++) { // inputs
390 uint sp=0;
392 int indx = (i & 0x20) | ((i & 1) << 4) | ((i >> 1) & 0xF);
394 for (int j = 0; j < 4; j++) { // for each bit in the output
395 if ((sBoxes [sOff + indx] & (8 >> j)) != 0) {
396 sp |= (uint) (1 << (31 - pBox [(s << 2) + j]));
400 spBoxes [sOff + i] = sp;
404 leftRotTotal = new byte [leftRot.Length];
406 for (int i = 0; i < leftRot.Length; i++) {
407 int r = 0;
408 for (int j = 0; j <= i; r += leftRot [j++]) {
409 // no statement (confuse the compiler == warning)
411 leftRotTotal [i] = (byte) r;
414 InitPermutationTable (ipBits, out ipTab);
415 InitPermutationTable (fpBits, out fpTab);
418 // Default constructor.
419 internal DESTransform (SymmetricAlgorithm symmAlgo, bool encryption, byte[] key, byte[] iv)
420 : base (symmAlgo, encryption, iv)
422 byte[] clonedKey = null;
423 if (key == null) {
424 key = GetStrongKey ();
425 clonedKey = key; // no need to clone
427 // note: checking (semi-)weak keys also checks valid key length
428 if (DES.IsWeakKey (key) || DES.IsSemiWeakKey (key)) {
429 string msg = Locale.GetText ("This is a known weak, or semi-weak, key.");
430 throw new CryptographicException (msg);
433 if (clonedKey == null)
434 clonedKey = (byte[]) key.Clone ();
436 keySchedule = new byte [KEY_BYTE_SIZE * 16];
437 byteBuff = new byte [BLOCK_BYTE_SIZE];
438 dwordBuff = new uint [BLOCK_BYTE_SIZE / 4];
439 SetKey (clonedKey);
442 /* Permutation Tables are now precomputed.
443 private static void InitPermutationTable (byte[] pBits, out int[] permTab)
445 permTab = new int [8*2 * 8*2 * (64/32)];
447 for (int i = 0; i < 16; i++) {
448 for (int j = 0; j < 16; j++) {
449 int offs = (i << 5) + (j << 1);
450 for (int n = 0; n < 64; n++) {
451 int bitNum = (int) pBits [n];
452 if ((bitNum >> 2 == i) &&
453 0 != (j & (8 >> (bitNum & 3)))) {
454 permTab [offs + (n >> (3+2))] |= (int) ((0x80808080 & (0xFF << (n & (3 << 3)))) >> (n & 7));
462 private uint CipherFunct (uint r, int n)
464 uint res = 0;
465 byte[] subkey = keySchedule;
466 int i = n << 3;
468 uint rt = (r >> 1) | (r << 31); // ROR32(r)
469 res |= spBoxes [0*64 + (((rt >> 26) ^ subkey [i++]) & 0x3F)];
470 res |= spBoxes [1*64 + (((rt >> 22) ^ subkey [i++]) & 0x3F)];
471 res |= spBoxes [2*64 + (((rt >> 18) ^ subkey [i++]) & 0x3F)];
472 res |= spBoxes [3*64 + (((rt >> 14) ^ subkey [i++]) & 0x3F)];
473 res |= spBoxes [4*64 + (((rt >> 10) ^ subkey [i++]) & 0x3F)];
474 res |= spBoxes [5*64 + (((rt >> 6) ^ subkey [i++]) & 0x3F)];
475 res |= spBoxes [6*64 + (((rt >> 2) ^ subkey [i++]) & 0x3F)];
476 rt = (r << 1) | (r >> 31); // ROL32(r)
477 res |= spBoxes [7*64 + ((rt ^ subkey [i]) & 0x3F)];
478 return res;
481 internal static void Permutation (byte[] input, byte[] output, uint[] permTab, bool preSwap)
483 if (preSwap && BitConverter.IsLittleEndian)
484 BSwap (input);
486 int offs1 = (((int)(input [0]) >> 4)) << 1;
487 int offs2 = (1 << 5) + ((((int)input [0]) & 0xF) << 1);
489 uint d1 = permTab [offs1++] | permTab [offs2++];
490 uint d2 = permTab [offs1] | permTab [offs2];
492 int max = BLOCK_BYTE_SIZE << 1;
493 for (int i = 2, indx = 1; i < max; i += 2, indx++) {
494 int ii = (int) input [indx];
495 offs1 = (i << 5) + ((ii >> 4) << 1);
496 offs2 = ((i + 1) << 5) + ((ii & 0xF) << 1);
498 d1 |= permTab [offs1++] | permTab [offs2++];
499 d2 |= permTab [offs1] | permTab [offs2];
502 if (preSwap || !BitConverter.IsLittleEndian) {
503 output [0] = (byte) (d1);
504 output [1] = (byte) (d1 >> 8);
505 output [2] = (byte) (d1 >> 16);
506 output [3] = (byte) (d1 >> 24);
507 output [4] = (byte) (d2);
508 output [5] = (byte) (d2 >> 8);
509 output [6] = (byte) (d2 >> 16);
510 output [7] = (byte) (d2 >> 24);
512 else {
513 output [0] = (byte) (d1 >> 24);
514 output [1] = (byte) (d1 >> 16);
515 output [2] = (byte) (d1 >> 8);
516 output [3] = (byte) (d1);
517 output [4] = (byte) (d2 >> 24);
518 output [5] = (byte) (d2 >> 16);
519 output [6] = (byte) (d2 >> 8);
520 output [7] = (byte) (d2);
524 private static void BSwap (byte [] byteBuff)
526 byte t = byteBuff [0];
527 byteBuff [0] = byteBuff [3];
528 byteBuff [3] = t;
530 t = byteBuff [1];
531 byteBuff [1] = byteBuff [2];
532 byteBuff [2] = t;
534 t = byteBuff [4];
535 byteBuff [4] = byteBuff [7];
536 byteBuff [7] = t;
538 t = byteBuff [5];
539 byteBuff [5] = byteBuff [6];
540 byteBuff [6] = t;
543 internal void SetKey (byte[] key)
545 // NOTE: see Fig. 3, Key schedule calculation, at page 20.
546 Array.Clear (keySchedule, 0, keySchedule.Length);
548 int keyBitSize = PC1.Length;
550 byte[] keyPC1 = new byte [keyBitSize]; // PC1-permuted key
551 byte[] keyRot = new byte [keyBitSize]; // PC1 & rotated
553 int indx = 0;
555 foreach (byte bitPos in PC1) {
556 keyPC1 [indx++] = (byte)((key [(int)bitPos >> 3] >> (7 ^ (bitPos & 7))) & 1);
559 int j;
560 for (int i = 0; i < KEY_BYTE_SIZE*2; i++) {
561 int b = keyBitSize >> 1;
563 for (j = 0; j < b; j++) {
564 int s = j + (int) leftRotTotal [i];
565 keyRot [j] = keyPC1 [s < b ? s : s - b];
568 for (j = b; j < keyBitSize; j++) {
569 int s = j + (int) leftRotTotal [i];
570 keyRot [j] = keyPC1 [s < keyBitSize ? s : s - b];
573 int keyOffs = i * KEY_BYTE_SIZE;
575 j = 0;
576 foreach (byte bitPos in PC2) {
577 if (keyRot [(int)bitPos] != 0) {
578 keySchedule [keyOffs + (j/6)] |= (byte) (0x80 >> ((j % 6) + 2));
580 j++;
585 // public helper for TripleDES
586 public void ProcessBlock (byte[] input, byte[] output)
588 Buffer.BlockCopy (input, 0, dwordBuff, 0, BLOCK_BYTE_SIZE);
590 if (encrypt) {
591 uint d0 = dwordBuff [0];
592 uint d1 = dwordBuff [1];
594 // 16 rounds
595 d0 ^= CipherFunct (d1, 0);
596 d1 ^= CipherFunct (d0, 1);
597 d0 ^= CipherFunct (d1, 2);
598 d1 ^= CipherFunct (d0, 3);
599 d0 ^= CipherFunct (d1, 4);
600 d1 ^= CipherFunct (d0, 5);
601 d0 ^= CipherFunct (d1, 6);
602 d1 ^= CipherFunct (d0, 7);
603 d0 ^= CipherFunct (d1, 8);
604 d1 ^= CipherFunct (d0, 9);
605 d0 ^= CipherFunct (d1, 10);
606 d1 ^= CipherFunct (d0, 11);
607 d0 ^= CipherFunct (d1, 12);
608 d1 ^= CipherFunct (d0, 13);
609 d0 ^= CipherFunct (d1, 14);
610 d1 ^= CipherFunct (d0, 15);
612 dwordBuff [0] = d1;
613 dwordBuff [1] = d0;
615 else {
616 uint d1 = dwordBuff [0];
617 uint d0 = dwordBuff [1];
619 // 16 rounds in reverse order
620 d1 ^= CipherFunct (d0, 15);
621 d0 ^= CipherFunct (d1, 14);
622 d1 ^= CipherFunct (d0, 13);
623 d0 ^= CipherFunct (d1, 12);
624 d1 ^= CipherFunct (d0, 11);
625 d0 ^= CipherFunct (d1, 10);
626 d1 ^= CipherFunct (d0, 9);
627 d0 ^= CipherFunct (d1, 8);
628 d1 ^= CipherFunct (d0, 7);
629 d0 ^= CipherFunct (d1, 6);
630 d1 ^= CipherFunct (d0, 5);
631 d0 ^= CipherFunct (d1, 4);
632 d1 ^= CipherFunct (d0, 3);
633 d0 ^= CipherFunct (d1, 2);
634 d1 ^= CipherFunct (d0, 1);
635 d0 ^= CipherFunct (d1, 0);
637 dwordBuff [0] = d0;
638 dwordBuff [1] = d1;
641 Buffer.BlockCopy (dwordBuff, 0, output, 0, BLOCK_BYTE_SIZE);
644 protected override void ECB (byte[] input, byte[] output)
646 Permutation (input, output, ipTab, false);
647 ProcessBlock (output, byteBuff);
648 Permutation (byteBuff, output, fpTab, true);
651 static internal byte[] GetStrongKey ()
653 byte[] key = KeyBuilder.Key (DESTransform.KEY_BYTE_SIZE);
654 while (DES.IsWeakKey (key) || DES.IsSemiWeakKey (key))
655 key = KeyBuilder.Key (DESTransform.KEY_BYTE_SIZE);
656 return key;