xref: /linux/crypto/des_generic.c (revision 16d004a2eda7be2c6a2de63eca2ad3c6b57307b3)
1c5a511f1SSebastian Siewior /*
2c5a511f1SSebastian Siewior  * Cryptographic API.
3c5a511f1SSebastian Siewior  *
4c5a511f1SSebastian Siewior  * DES & Triple DES EDE Cipher Algorithms.
5c5a511f1SSebastian Siewior  *
6c5a511f1SSebastian Siewior  * Copyright (c) 2005 Dag Arne Osvik <da@osvik.no>
7c5a511f1SSebastian Siewior  *
8c5a511f1SSebastian Siewior  * This program is free software; you can redistribute it and/or modify
9c5a511f1SSebastian Siewior  * it under the terms of the GNU General Public License as published by
10c5a511f1SSebastian Siewior  * the Free Software Foundation; either version 2 of the License, or
11c5a511f1SSebastian Siewior  * (at your option) any later version.
12c5a511f1SSebastian Siewior  *
13c5a511f1SSebastian Siewior  */
14c5a511f1SSebastian Siewior 
15c5a511f1SSebastian Siewior #include <asm/byteorder.h>
16c5a511f1SSebastian Siewior #include <linux/bitops.h>
17c5a511f1SSebastian Siewior #include <linux/init.h>
18c5a511f1SSebastian Siewior #include <linux/module.h>
19c5a511f1SSebastian Siewior #include <linux/errno.h>
20c5a511f1SSebastian Siewior #include <linux/crypto.h>
21c5a511f1SSebastian Siewior #include <linux/types.h>
22c5a511f1SSebastian Siewior 
23*16d004a2SEvgeniy Polyakov #include <crypto/des.h>
24c5a511f1SSebastian Siewior 
25c5a511f1SSebastian Siewior #define ROL(x, r) ((x) = rol32((x), (r)))
26c5a511f1SSebastian Siewior #define ROR(x, r) ((x) = ror32((x), (r)))
27c5a511f1SSebastian Siewior 
28c5a511f1SSebastian Siewior struct des_ctx {
29c5a511f1SSebastian Siewior 	u32 expkey[DES_EXPKEY_WORDS];
30c5a511f1SSebastian Siewior };
31c5a511f1SSebastian Siewior 
32c5a511f1SSebastian Siewior struct des3_ede_ctx {
33c5a511f1SSebastian Siewior 	u32 expkey[DES3_EDE_EXPKEY_WORDS];
34c5a511f1SSebastian Siewior };
35c5a511f1SSebastian Siewior 
36c5a511f1SSebastian Siewior /* Lookup tables for key expansion */
37c5a511f1SSebastian Siewior 
38c5a511f1SSebastian Siewior static const u8 pc1[256] = {
39c5a511f1SSebastian Siewior 	0x00, 0x00, 0x40, 0x04, 0x10, 0x10, 0x50, 0x14,
40c5a511f1SSebastian Siewior 	0x04, 0x40, 0x44, 0x44, 0x14, 0x50, 0x54, 0x54,
41c5a511f1SSebastian Siewior 	0x02, 0x02, 0x42, 0x06, 0x12, 0x12, 0x52, 0x16,
42c5a511f1SSebastian Siewior 	0x06, 0x42, 0x46, 0x46, 0x16, 0x52, 0x56, 0x56,
43c5a511f1SSebastian Siewior 	0x80, 0x08, 0xc0, 0x0c, 0x90, 0x18, 0xd0, 0x1c,
44c5a511f1SSebastian Siewior 	0x84, 0x48, 0xc4, 0x4c, 0x94, 0x58, 0xd4, 0x5c,
45c5a511f1SSebastian Siewior 	0x82, 0x0a, 0xc2, 0x0e, 0x92, 0x1a, 0xd2, 0x1e,
46c5a511f1SSebastian Siewior 	0x86, 0x4a, 0xc6, 0x4e, 0x96, 0x5a, 0xd6, 0x5e,
47c5a511f1SSebastian Siewior 	0x20, 0x20, 0x60, 0x24, 0x30, 0x30, 0x70, 0x34,
48c5a511f1SSebastian Siewior 	0x24, 0x60, 0x64, 0x64, 0x34, 0x70, 0x74, 0x74,
49c5a511f1SSebastian Siewior 	0x22, 0x22, 0x62, 0x26, 0x32, 0x32, 0x72, 0x36,
50c5a511f1SSebastian Siewior 	0x26, 0x62, 0x66, 0x66, 0x36, 0x72, 0x76, 0x76,
51c5a511f1SSebastian Siewior 	0xa0, 0x28, 0xe0, 0x2c, 0xb0, 0x38, 0xf0, 0x3c,
52c5a511f1SSebastian Siewior 	0xa4, 0x68, 0xe4, 0x6c, 0xb4, 0x78, 0xf4, 0x7c,
53c5a511f1SSebastian Siewior 	0xa2, 0x2a, 0xe2, 0x2e, 0xb2, 0x3a, 0xf2, 0x3e,
54c5a511f1SSebastian Siewior 	0xa6, 0x6a, 0xe6, 0x6e, 0xb6, 0x7a, 0xf6, 0x7e,
55c5a511f1SSebastian Siewior 	0x08, 0x80, 0x48, 0x84, 0x18, 0x90, 0x58, 0x94,
56c5a511f1SSebastian Siewior 	0x0c, 0xc0, 0x4c, 0xc4, 0x1c, 0xd0, 0x5c, 0xd4,
57c5a511f1SSebastian Siewior 	0x0a, 0x82, 0x4a, 0x86, 0x1a, 0x92, 0x5a, 0x96,
58c5a511f1SSebastian Siewior 	0x0e, 0xc2, 0x4e, 0xc6, 0x1e, 0xd2, 0x5e, 0xd6,
59c5a511f1SSebastian Siewior 	0x88, 0x88, 0xc8, 0x8c, 0x98, 0x98, 0xd8, 0x9c,
60c5a511f1SSebastian Siewior 	0x8c, 0xc8, 0xcc, 0xcc, 0x9c, 0xd8, 0xdc, 0xdc,
61c5a511f1SSebastian Siewior 	0x8a, 0x8a, 0xca, 0x8e, 0x9a, 0x9a, 0xda, 0x9e,
62c5a511f1SSebastian Siewior 	0x8e, 0xca, 0xce, 0xce, 0x9e, 0xda, 0xde, 0xde,
63c5a511f1SSebastian Siewior 	0x28, 0xa0, 0x68, 0xa4, 0x38, 0xb0, 0x78, 0xb4,
64c5a511f1SSebastian Siewior 	0x2c, 0xe0, 0x6c, 0xe4, 0x3c, 0xf0, 0x7c, 0xf4,
65c5a511f1SSebastian Siewior 	0x2a, 0xa2, 0x6a, 0xa6, 0x3a, 0xb2, 0x7a, 0xb6,
66c5a511f1SSebastian Siewior 	0x2e, 0xe2, 0x6e, 0xe6, 0x3e, 0xf2, 0x7e, 0xf6,
67c5a511f1SSebastian Siewior 	0xa8, 0xa8, 0xe8, 0xac, 0xb8, 0xb8, 0xf8, 0xbc,
68c5a511f1SSebastian Siewior 	0xac, 0xe8, 0xec, 0xec, 0xbc, 0xf8, 0xfc, 0xfc,
69c5a511f1SSebastian Siewior 	0xaa, 0xaa, 0xea, 0xae, 0xba, 0xba, 0xfa, 0xbe,
70c5a511f1SSebastian Siewior 	0xae, 0xea, 0xee, 0xee, 0xbe, 0xfa, 0xfe, 0xfe
71c5a511f1SSebastian Siewior };
72c5a511f1SSebastian Siewior 
73c5a511f1SSebastian Siewior static const u8 rs[256] = {
74c5a511f1SSebastian Siewior 	0x00, 0x00, 0x80, 0x80, 0x02, 0x02, 0x82, 0x82,
75c5a511f1SSebastian Siewior 	0x04, 0x04, 0x84, 0x84, 0x06, 0x06, 0x86, 0x86,
76c5a511f1SSebastian Siewior 	0x08, 0x08, 0x88, 0x88, 0x0a, 0x0a, 0x8a, 0x8a,
77c5a511f1SSebastian Siewior 	0x0c, 0x0c, 0x8c, 0x8c, 0x0e, 0x0e, 0x8e, 0x8e,
78c5a511f1SSebastian Siewior 	0x10, 0x10, 0x90, 0x90, 0x12, 0x12, 0x92, 0x92,
79c5a511f1SSebastian Siewior 	0x14, 0x14, 0x94, 0x94, 0x16, 0x16, 0x96, 0x96,
80c5a511f1SSebastian Siewior 	0x18, 0x18, 0x98, 0x98, 0x1a, 0x1a, 0x9a, 0x9a,
81c5a511f1SSebastian Siewior 	0x1c, 0x1c, 0x9c, 0x9c, 0x1e, 0x1e, 0x9e, 0x9e,
82c5a511f1SSebastian Siewior 	0x20, 0x20, 0xa0, 0xa0, 0x22, 0x22, 0xa2, 0xa2,
83c5a511f1SSebastian Siewior 	0x24, 0x24, 0xa4, 0xa4, 0x26, 0x26, 0xa6, 0xa6,
84c5a511f1SSebastian Siewior 	0x28, 0x28, 0xa8, 0xa8, 0x2a, 0x2a, 0xaa, 0xaa,
85c5a511f1SSebastian Siewior 	0x2c, 0x2c, 0xac, 0xac, 0x2e, 0x2e, 0xae, 0xae,
86c5a511f1SSebastian Siewior 	0x30, 0x30, 0xb0, 0xb0, 0x32, 0x32, 0xb2, 0xb2,
87c5a511f1SSebastian Siewior 	0x34, 0x34, 0xb4, 0xb4, 0x36, 0x36, 0xb6, 0xb6,
88c5a511f1SSebastian Siewior 	0x38, 0x38, 0xb8, 0xb8, 0x3a, 0x3a, 0xba, 0xba,
89c5a511f1SSebastian Siewior 	0x3c, 0x3c, 0xbc, 0xbc, 0x3e, 0x3e, 0xbe, 0xbe,
90c5a511f1SSebastian Siewior 	0x40, 0x40, 0xc0, 0xc0, 0x42, 0x42, 0xc2, 0xc2,
91c5a511f1SSebastian Siewior 	0x44, 0x44, 0xc4, 0xc4, 0x46, 0x46, 0xc6, 0xc6,
92c5a511f1SSebastian Siewior 	0x48, 0x48, 0xc8, 0xc8, 0x4a, 0x4a, 0xca, 0xca,
93c5a511f1SSebastian Siewior 	0x4c, 0x4c, 0xcc, 0xcc, 0x4e, 0x4e, 0xce, 0xce,
94c5a511f1SSebastian Siewior 	0x50, 0x50, 0xd0, 0xd0, 0x52, 0x52, 0xd2, 0xd2,
95c5a511f1SSebastian Siewior 	0x54, 0x54, 0xd4, 0xd4, 0x56, 0x56, 0xd6, 0xd6,
96c5a511f1SSebastian Siewior 	0x58, 0x58, 0xd8, 0xd8, 0x5a, 0x5a, 0xda, 0xda,
97c5a511f1SSebastian Siewior 	0x5c, 0x5c, 0xdc, 0xdc, 0x5e, 0x5e, 0xde, 0xde,
98c5a511f1SSebastian Siewior 	0x60, 0x60, 0xe0, 0xe0, 0x62, 0x62, 0xe2, 0xe2,
99c5a511f1SSebastian Siewior 	0x64, 0x64, 0xe4, 0xe4, 0x66, 0x66, 0xe6, 0xe6,
100c5a511f1SSebastian Siewior 	0x68, 0x68, 0xe8, 0xe8, 0x6a, 0x6a, 0xea, 0xea,
101c5a511f1SSebastian Siewior 	0x6c, 0x6c, 0xec, 0xec, 0x6e, 0x6e, 0xee, 0xee,
102c5a511f1SSebastian Siewior 	0x70, 0x70, 0xf0, 0xf0, 0x72, 0x72, 0xf2, 0xf2,
103c5a511f1SSebastian Siewior 	0x74, 0x74, 0xf4, 0xf4, 0x76, 0x76, 0xf6, 0xf6,
104c5a511f1SSebastian Siewior 	0x78, 0x78, 0xf8, 0xf8, 0x7a, 0x7a, 0xfa, 0xfa,
105c5a511f1SSebastian Siewior 	0x7c, 0x7c, 0xfc, 0xfc, 0x7e, 0x7e, 0xfe, 0xfe
106c5a511f1SSebastian Siewior };
107c5a511f1SSebastian Siewior 
108c5a511f1SSebastian Siewior static const u32 pc2[1024] = {
109c5a511f1SSebastian Siewior 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
110c5a511f1SSebastian Siewior 	0x00040000, 0x00000000, 0x04000000, 0x00100000,
111c5a511f1SSebastian Siewior 	0x00400000, 0x00000008, 0x00000800, 0x40000000,
112c5a511f1SSebastian Siewior 	0x00440000, 0x00000008, 0x04000800, 0x40100000,
113c5a511f1SSebastian Siewior 	0x00000400, 0x00000020, 0x08000000, 0x00000100,
114c5a511f1SSebastian Siewior 	0x00040400, 0x00000020, 0x0c000000, 0x00100100,
115c5a511f1SSebastian Siewior 	0x00400400, 0x00000028, 0x08000800, 0x40000100,
116c5a511f1SSebastian Siewior 	0x00440400, 0x00000028, 0x0c000800, 0x40100100,
117c5a511f1SSebastian Siewior 	0x80000000, 0x00000010, 0x00000000, 0x00800000,
118c5a511f1SSebastian Siewior 	0x80040000, 0x00000010, 0x04000000, 0x00900000,
119c5a511f1SSebastian Siewior 	0x80400000, 0x00000018, 0x00000800, 0x40800000,
120c5a511f1SSebastian Siewior 	0x80440000, 0x00000018, 0x04000800, 0x40900000,
121c5a511f1SSebastian Siewior 	0x80000400, 0x00000030, 0x08000000, 0x00800100,
122c5a511f1SSebastian Siewior 	0x80040400, 0x00000030, 0x0c000000, 0x00900100,
123c5a511f1SSebastian Siewior 	0x80400400, 0x00000038, 0x08000800, 0x40800100,
124c5a511f1SSebastian Siewior 	0x80440400, 0x00000038, 0x0c000800, 0x40900100,
125c5a511f1SSebastian Siewior 	0x10000000, 0x00000000, 0x00200000, 0x00001000,
126c5a511f1SSebastian Siewior 	0x10040000, 0x00000000, 0x04200000, 0x00101000,
127c5a511f1SSebastian Siewior 	0x10400000, 0x00000008, 0x00200800, 0x40001000,
128c5a511f1SSebastian Siewior 	0x10440000, 0x00000008, 0x04200800, 0x40101000,
129c5a511f1SSebastian Siewior 	0x10000400, 0x00000020, 0x08200000, 0x00001100,
130c5a511f1SSebastian Siewior 	0x10040400, 0x00000020, 0x0c200000, 0x00101100,
131c5a511f1SSebastian Siewior 	0x10400400, 0x00000028, 0x08200800, 0x40001100,
132c5a511f1SSebastian Siewior 	0x10440400, 0x00000028, 0x0c200800, 0x40101100,
133c5a511f1SSebastian Siewior 	0x90000000, 0x00000010, 0x00200000, 0x00801000,
134c5a511f1SSebastian Siewior 	0x90040000, 0x00000010, 0x04200000, 0x00901000,
135c5a511f1SSebastian Siewior 	0x90400000, 0x00000018, 0x00200800, 0x40801000,
136c5a511f1SSebastian Siewior 	0x90440000, 0x00000018, 0x04200800, 0x40901000,
137c5a511f1SSebastian Siewior 	0x90000400, 0x00000030, 0x08200000, 0x00801100,
138c5a511f1SSebastian Siewior 	0x90040400, 0x00000030, 0x0c200000, 0x00901100,
139c5a511f1SSebastian Siewior 	0x90400400, 0x00000038, 0x08200800, 0x40801100,
140c5a511f1SSebastian Siewior 	0x90440400, 0x00000038, 0x0c200800, 0x40901100,
141c5a511f1SSebastian Siewior 	0x00000200, 0x00080000, 0x00000000, 0x00000004,
142c5a511f1SSebastian Siewior 	0x00040200, 0x00080000, 0x04000000, 0x00100004,
143c5a511f1SSebastian Siewior 	0x00400200, 0x00080008, 0x00000800, 0x40000004,
144c5a511f1SSebastian Siewior 	0x00440200, 0x00080008, 0x04000800, 0x40100004,
145c5a511f1SSebastian Siewior 	0x00000600, 0x00080020, 0x08000000, 0x00000104,
146c5a511f1SSebastian Siewior 	0x00040600, 0x00080020, 0x0c000000, 0x00100104,
147c5a511f1SSebastian Siewior 	0x00400600, 0x00080028, 0x08000800, 0x40000104,
148c5a511f1SSebastian Siewior 	0x00440600, 0x00080028, 0x0c000800, 0x40100104,
149c5a511f1SSebastian Siewior 	0x80000200, 0x00080010, 0x00000000, 0x00800004,
150c5a511f1SSebastian Siewior 	0x80040200, 0x00080010, 0x04000000, 0x00900004,
151c5a511f1SSebastian Siewior 	0x80400200, 0x00080018, 0x00000800, 0x40800004,
152c5a511f1SSebastian Siewior 	0x80440200, 0x00080018, 0x04000800, 0x40900004,
153c5a511f1SSebastian Siewior 	0x80000600, 0x00080030, 0x08000000, 0x00800104,
154c5a511f1SSebastian Siewior 	0x80040600, 0x00080030, 0x0c000000, 0x00900104,
155c5a511f1SSebastian Siewior 	0x80400600, 0x00080038, 0x08000800, 0x40800104,
156c5a511f1SSebastian Siewior 	0x80440600, 0x00080038, 0x0c000800, 0x40900104,
157c5a511f1SSebastian Siewior 	0x10000200, 0x00080000, 0x00200000, 0x00001004,
158c5a511f1SSebastian Siewior 	0x10040200, 0x00080000, 0x04200000, 0x00101004,
159c5a511f1SSebastian Siewior 	0x10400200, 0x00080008, 0x00200800, 0x40001004,
160c5a511f1SSebastian Siewior 	0x10440200, 0x00080008, 0x04200800, 0x40101004,
161c5a511f1SSebastian Siewior 	0x10000600, 0x00080020, 0x08200000, 0x00001104,
162c5a511f1SSebastian Siewior 	0x10040600, 0x00080020, 0x0c200000, 0x00101104,
163c5a511f1SSebastian Siewior 	0x10400600, 0x00080028, 0x08200800, 0x40001104,
164c5a511f1SSebastian Siewior 	0x10440600, 0x00080028, 0x0c200800, 0x40101104,
165c5a511f1SSebastian Siewior 	0x90000200, 0x00080010, 0x00200000, 0x00801004,
166c5a511f1SSebastian Siewior 	0x90040200, 0x00080010, 0x04200000, 0x00901004,
167c5a511f1SSebastian Siewior 	0x90400200, 0x00080018, 0x00200800, 0x40801004,
168c5a511f1SSebastian Siewior 	0x90440200, 0x00080018, 0x04200800, 0x40901004,
169c5a511f1SSebastian Siewior 	0x90000600, 0x00080030, 0x08200000, 0x00801104,
170c5a511f1SSebastian Siewior 	0x90040600, 0x00080030, 0x0c200000, 0x00901104,
171c5a511f1SSebastian Siewior 	0x90400600, 0x00080038, 0x08200800, 0x40801104,
172c5a511f1SSebastian Siewior 	0x90440600, 0x00080038, 0x0c200800, 0x40901104,
173c5a511f1SSebastian Siewior 	0x00000002, 0x00002000, 0x20000000, 0x00000001,
174c5a511f1SSebastian Siewior 	0x00040002, 0x00002000, 0x24000000, 0x00100001,
175c5a511f1SSebastian Siewior 	0x00400002, 0x00002008, 0x20000800, 0x40000001,
176c5a511f1SSebastian Siewior 	0x00440002, 0x00002008, 0x24000800, 0x40100001,
177c5a511f1SSebastian Siewior 	0x00000402, 0x00002020, 0x28000000, 0x00000101,
178c5a511f1SSebastian Siewior 	0x00040402, 0x00002020, 0x2c000000, 0x00100101,
179c5a511f1SSebastian Siewior 	0x00400402, 0x00002028, 0x28000800, 0x40000101,
180c5a511f1SSebastian Siewior 	0x00440402, 0x00002028, 0x2c000800, 0x40100101,
181c5a511f1SSebastian Siewior 	0x80000002, 0x00002010, 0x20000000, 0x00800001,
182c5a511f1SSebastian Siewior 	0x80040002, 0x00002010, 0x24000000, 0x00900001,
183c5a511f1SSebastian Siewior 	0x80400002, 0x00002018, 0x20000800, 0x40800001,
184c5a511f1SSebastian Siewior 	0x80440002, 0x00002018, 0x24000800, 0x40900001,
185c5a511f1SSebastian Siewior 	0x80000402, 0x00002030, 0x28000000, 0x00800101,
186c5a511f1SSebastian Siewior 	0x80040402, 0x00002030, 0x2c000000, 0x00900101,
187c5a511f1SSebastian Siewior 	0x80400402, 0x00002038, 0x28000800, 0x40800101,
188c5a511f1SSebastian Siewior 	0x80440402, 0x00002038, 0x2c000800, 0x40900101,
189c5a511f1SSebastian Siewior 	0x10000002, 0x00002000, 0x20200000, 0x00001001,
190c5a511f1SSebastian Siewior 	0x10040002, 0x00002000, 0x24200000, 0x00101001,
191c5a511f1SSebastian Siewior 	0x10400002, 0x00002008, 0x20200800, 0x40001001,
192c5a511f1SSebastian Siewior 	0x10440002, 0x00002008, 0x24200800, 0x40101001,
193c5a511f1SSebastian Siewior 	0x10000402, 0x00002020, 0x28200000, 0x00001101,
194c5a511f1SSebastian Siewior 	0x10040402, 0x00002020, 0x2c200000, 0x00101101,
195c5a511f1SSebastian Siewior 	0x10400402, 0x00002028, 0x28200800, 0x40001101,
196c5a511f1SSebastian Siewior 	0x10440402, 0x00002028, 0x2c200800, 0x40101101,
197c5a511f1SSebastian Siewior 	0x90000002, 0x00002010, 0x20200000, 0x00801001,
198c5a511f1SSebastian Siewior 	0x90040002, 0x00002010, 0x24200000, 0x00901001,
199c5a511f1SSebastian Siewior 	0x90400002, 0x00002018, 0x20200800, 0x40801001,
200c5a511f1SSebastian Siewior 	0x90440002, 0x00002018, 0x24200800, 0x40901001,
201c5a511f1SSebastian Siewior 	0x90000402, 0x00002030, 0x28200000, 0x00801101,
202c5a511f1SSebastian Siewior 	0x90040402, 0x00002030, 0x2c200000, 0x00901101,
203c5a511f1SSebastian Siewior 	0x90400402, 0x00002038, 0x28200800, 0x40801101,
204c5a511f1SSebastian Siewior 	0x90440402, 0x00002038, 0x2c200800, 0x40901101,
205c5a511f1SSebastian Siewior 	0x00000202, 0x00082000, 0x20000000, 0x00000005,
206c5a511f1SSebastian Siewior 	0x00040202, 0x00082000, 0x24000000, 0x00100005,
207c5a511f1SSebastian Siewior 	0x00400202, 0x00082008, 0x20000800, 0x40000005,
208c5a511f1SSebastian Siewior 	0x00440202, 0x00082008, 0x24000800, 0x40100005,
209c5a511f1SSebastian Siewior 	0x00000602, 0x00082020, 0x28000000, 0x00000105,
210c5a511f1SSebastian Siewior 	0x00040602, 0x00082020, 0x2c000000, 0x00100105,
211c5a511f1SSebastian Siewior 	0x00400602, 0x00082028, 0x28000800, 0x40000105,
212c5a511f1SSebastian Siewior 	0x00440602, 0x00082028, 0x2c000800, 0x40100105,
213c5a511f1SSebastian Siewior 	0x80000202, 0x00082010, 0x20000000, 0x00800005,
214c5a511f1SSebastian Siewior 	0x80040202, 0x00082010, 0x24000000, 0x00900005,
215c5a511f1SSebastian Siewior 	0x80400202, 0x00082018, 0x20000800, 0x40800005,
216c5a511f1SSebastian Siewior 	0x80440202, 0x00082018, 0x24000800, 0x40900005,
217c5a511f1SSebastian Siewior 	0x80000602, 0x00082030, 0x28000000, 0x00800105,
218c5a511f1SSebastian Siewior 	0x80040602, 0x00082030, 0x2c000000, 0x00900105,
219c5a511f1SSebastian Siewior 	0x80400602, 0x00082038, 0x28000800, 0x40800105,
220c5a511f1SSebastian Siewior 	0x80440602, 0x00082038, 0x2c000800, 0x40900105,
221c5a511f1SSebastian Siewior 	0x10000202, 0x00082000, 0x20200000, 0x00001005,
222c5a511f1SSebastian Siewior 	0x10040202, 0x00082000, 0x24200000, 0x00101005,
223c5a511f1SSebastian Siewior 	0x10400202, 0x00082008, 0x20200800, 0x40001005,
224c5a511f1SSebastian Siewior 	0x10440202, 0x00082008, 0x24200800, 0x40101005,
225c5a511f1SSebastian Siewior 	0x10000602, 0x00082020, 0x28200000, 0x00001105,
226c5a511f1SSebastian Siewior 	0x10040602, 0x00082020, 0x2c200000, 0x00101105,
227c5a511f1SSebastian Siewior 	0x10400602, 0x00082028, 0x28200800, 0x40001105,
228c5a511f1SSebastian Siewior 	0x10440602, 0x00082028, 0x2c200800, 0x40101105,
229c5a511f1SSebastian Siewior 	0x90000202, 0x00082010, 0x20200000, 0x00801005,
230c5a511f1SSebastian Siewior 	0x90040202, 0x00082010, 0x24200000, 0x00901005,
231c5a511f1SSebastian Siewior 	0x90400202, 0x00082018, 0x20200800, 0x40801005,
232c5a511f1SSebastian Siewior 	0x90440202, 0x00082018, 0x24200800, 0x40901005,
233c5a511f1SSebastian Siewior 	0x90000602, 0x00082030, 0x28200000, 0x00801105,
234c5a511f1SSebastian Siewior 	0x90040602, 0x00082030, 0x2c200000, 0x00901105,
235c5a511f1SSebastian Siewior 	0x90400602, 0x00082038, 0x28200800, 0x40801105,
236c5a511f1SSebastian Siewior 	0x90440602, 0x00082038, 0x2c200800, 0x40901105,
237c5a511f1SSebastian Siewior 
238c5a511f1SSebastian Siewior 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
239c5a511f1SSebastian Siewior 	0x00000000, 0x00000008, 0x00080000, 0x10000000,
240c5a511f1SSebastian Siewior 	0x02000000, 0x00000000, 0x00000080, 0x00001000,
241c5a511f1SSebastian Siewior 	0x02000000, 0x00000008, 0x00080080, 0x10001000,
242c5a511f1SSebastian Siewior 	0x00004000, 0x00000000, 0x00000040, 0x00040000,
243c5a511f1SSebastian Siewior 	0x00004000, 0x00000008, 0x00080040, 0x10040000,
244c5a511f1SSebastian Siewior 	0x02004000, 0x00000000, 0x000000c0, 0x00041000,
245c5a511f1SSebastian Siewior 	0x02004000, 0x00000008, 0x000800c0, 0x10041000,
246c5a511f1SSebastian Siewior 	0x00020000, 0x00008000, 0x08000000, 0x00200000,
247c5a511f1SSebastian Siewior 	0x00020000, 0x00008008, 0x08080000, 0x10200000,
248c5a511f1SSebastian Siewior 	0x02020000, 0x00008000, 0x08000080, 0x00201000,
249c5a511f1SSebastian Siewior 	0x02020000, 0x00008008, 0x08080080, 0x10201000,
250c5a511f1SSebastian Siewior 	0x00024000, 0x00008000, 0x08000040, 0x00240000,
251c5a511f1SSebastian Siewior 	0x00024000, 0x00008008, 0x08080040, 0x10240000,
252c5a511f1SSebastian Siewior 	0x02024000, 0x00008000, 0x080000c0, 0x00241000,
253c5a511f1SSebastian Siewior 	0x02024000, 0x00008008, 0x080800c0, 0x10241000,
254c5a511f1SSebastian Siewior 	0x00000000, 0x01000000, 0x00002000, 0x00000020,
255c5a511f1SSebastian Siewior 	0x00000000, 0x01000008, 0x00082000, 0x10000020,
256c5a511f1SSebastian Siewior 	0x02000000, 0x01000000, 0x00002080, 0x00001020,
257c5a511f1SSebastian Siewior 	0x02000000, 0x01000008, 0x00082080, 0x10001020,
258c5a511f1SSebastian Siewior 	0x00004000, 0x01000000, 0x00002040, 0x00040020,
259c5a511f1SSebastian Siewior 	0x00004000, 0x01000008, 0x00082040, 0x10040020,
260c5a511f1SSebastian Siewior 	0x02004000, 0x01000000, 0x000020c0, 0x00041020,
261c5a511f1SSebastian Siewior 	0x02004000, 0x01000008, 0x000820c0, 0x10041020,
262c5a511f1SSebastian Siewior 	0x00020000, 0x01008000, 0x08002000, 0x00200020,
263c5a511f1SSebastian Siewior 	0x00020000, 0x01008008, 0x08082000, 0x10200020,
264c5a511f1SSebastian Siewior 	0x02020000, 0x01008000, 0x08002080, 0x00201020,
265c5a511f1SSebastian Siewior 	0x02020000, 0x01008008, 0x08082080, 0x10201020,
266c5a511f1SSebastian Siewior 	0x00024000, 0x01008000, 0x08002040, 0x00240020,
267c5a511f1SSebastian Siewior 	0x00024000, 0x01008008, 0x08082040, 0x10240020,
268c5a511f1SSebastian Siewior 	0x02024000, 0x01008000, 0x080020c0, 0x00241020,
269c5a511f1SSebastian Siewior 	0x02024000, 0x01008008, 0x080820c0, 0x10241020,
270c5a511f1SSebastian Siewior 	0x00000400, 0x04000000, 0x00100000, 0x00000004,
271c5a511f1SSebastian Siewior 	0x00000400, 0x04000008, 0x00180000, 0x10000004,
272c5a511f1SSebastian Siewior 	0x02000400, 0x04000000, 0x00100080, 0x00001004,
273c5a511f1SSebastian Siewior 	0x02000400, 0x04000008, 0x00180080, 0x10001004,
274c5a511f1SSebastian Siewior 	0x00004400, 0x04000000, 0x00100040, 0x00040004,
275c5a511f1SSebastian Siewior 	0x00004400, 0x04000008, 0x00180040, 0x10040004,
276c5a511f1SSebastian Siewior 	0x02004400, 0x04000000, 0x001000c0, 0x00041004,
277c5a511f1SSebastian Siewior 	0x02004400, 0x04000008, 0x001800c0, 0x10041004,
278c5a511f1SSebastian Siewior 	0x00020400, 0x04008000, 0x08100000, 0x00200004,
279c5a511f1SSebastian Siewior 	0x00020400, 0x04008008, 0x08180000, 0x10200004,
280c5a511f1SSebastian Siewior 	0x02020400, 0x04008000, 0x08100080, 0x00201004,
281c5a511f1SSebastian Siewior 	0x02020400, 0x04008008, 0x08180080, 0x10201004,
282c5a511f1SSebastian Siewior 	0x00024400, 0x04008000, 0x08100040, 0x00240004,
283c5a511f1SSebastian Siewior 	0x00024400, 0x04008008, 0x08180040, 0x10240004,
284c5a511f1SSebastian Siewior 	0x02024400, 0x04008000, 0x081000c0, 0x00241004,
285c5a511f1SSebastian Siewior 	0x02024400, 0x04008008, 0x081800c0, 0x10241004,
286c5a511f1SSebastian Siewior 	0x00000400, 0x05000000, 0x00102000, 0x00000024,
287c5a511f1SSebastian Siewior 	0x00000400, 0x05000008, 0x00182000, 0x10000024,
288c5a511f1SSebastian Siewior 	0x02000400, 0x05000000, 0x00102080, 0x00001024,
289c5a511f1SSebastian Siewior 	0x02000400, 0x05000008, 0x00182080, 0x10001024,
290c5a511f1SSebastian Siewior 	0x00004400, 0x05000000, 0x00102040, 0x00040024,
291c5a511f1SSebastian Siewior 	0x00004400, 0x05000008, 0x00182040, 0x10040024,
292c5a511f1SSebastian Siewior 	0x02004400, 0x05000000, 0x001020c0, 0x00041024,
293c5a511f1SSebastian Siewior 	0x02004400, 0x05000008, 0x001820c0, 0x10041024,
294c5a511f1SSebastian Siewior 	0x00020400, 0x05008000, 0x08102000, 0x00200024,
295c5a511f1SSebastian Siewior 	0x00020400, 0x05008008, 0x08182000, 0x10200024,
296c5a511f1SSebastian Siewior 	0x02020400, 0x05008000, 0x08102080, 0x00201024,
297c5a511f1SSebastian Siewior 	0x02020400, 0x05008008, 0x08182080, 0x10201024,
298c5a511f1SSebastian Siewior 	0x00024400, 0x05008000, 0x08102040, 0x00240024,
299c5a511f1SSebastian Siewior 	0x00024400, 0x05008008, 0x08182040, 0x10240024,
300c5a511f1SSebastian Siewior 	0x02024400, 0x05008000, 0x081020c0, 0x00241024,
301c5a511f1SSebastian Siewior 	0x02024400, 0x05008008, 0x081820c0, 0x10241024,
302c5a511f1SSebastian Siewior 	0x00000800, 0x00010000, 0x20000000, 0x00000010,
303c5a511f1SSebastian Siewior 	0x00000800, 0x00010008, 0x20080000, 0x10000010,
304c5a511f1SSebastian Siewior 	0x02000800, 0x00010000, 0x20000080, 0x00001010,
305c5a511f1SSebastian Siewior 	0x02000800, 0x00010008, 0x20080080, 0x10001010,
306c5a511f1SSebastian Siewior 	0x00004800, 0x00010000, 0x20000040, 0x00040010,
307c5a511f1SSebastian Siewior 	0x00004800, 0x00010008, 0x20080040, 0x10040010,
308c5a511f1SSebastian Siewior 	0x02004800, 0x00010000, 0x200000c0, 0x00041010,
309c5a511f1SSebastian Siewior 	0x02004800, 0x00010008, 0x200800c0, 0x10041010,
310c5a511f1SSebastian Siewior 	0x00020800, 0x00018000, 0x28000000, 0x00200010,
311c5a511f1SSebastian Siewior 	0x00020800, 0x00018008, 0x28080000, 0x10200010,
312c5a511f1SSebastian Siewior 	0x02020800, 0x00018000, 0x28000080, 0x00201010,
313c5a511f1SSebastian Siewior 	0x02020800, 0x00018008, 0x28080080, 0x10201010,
314c5a511f1SSebastian Siewior 	0x00024800, 0x00018000, 0x28000040, 0x00240010,
315c5a511f1SSebastian Siewior 	0x00024800, 0x00018008, 0x28080040, 0x10240010,
316c5a511f1SSebastian Siewior 	0x02024800, 0x00018000, 0x280000c0, 0x00241010,
317c5a511f1SSebastian Siewior 	0x02024800, 0x00018008, 0x280800c0, 0x10241010,
318c5a511f1SSebastian Siewior 	0x00000800, 0x01010000, 0x20002000, 0x00000030,
319c5a511f1SSebastian Siewior 	0x00000800, 0x01010008, 0x20082000, 0x10000030,
320c5a511f1SSebastian Siewior 	0x02000800, 0x01010000, 0x20002080, 0x00001030,
321c5a511f1SSebastian Siewior 	0x02000800, 0x01010008, 0x20082080, 0x10001030,
322c5a511f1SSebastian Siewior 	0x00004800, 0x01010000, 0x20002040, 0x00040030,
323c5a511f1SSebastian Siewior 	0x00004800, 0x01010008, 0x20082040, 0x10040030,
324c5a511f1SSebastian Siewior 	0x02004800, 0x01010000, 0x200020c0, 0x00041030,
325c5a511f1SSebastian Siewior 	0x02004800, 0x01010008, 0x200820c0, 0x10041030,
326c5a511f1SSebastian Siewior 	0x00020800, 0x01018000, 0x28002000, 0x00200030,
327c5a511f1SSebastian Siewior 	0x00020800, 0x01018008, 0x28082000, 0x10200030,
328c5a511f1SSebastian Siewior 	0x02020800, 0x01018000, 0x28002080, 0x00201030,
329c5a511f1SSebastian Siewior 	0x02020800, 0x01018008, 0x28082080, 0x10201030,
330c5a511f1SSebastian Siewior 	0x00024800, 0x01018000, 0x28002040, 0x00240030,
331c5a511f1SSebastian Siewior 	0x00024800, 0x01018008, 0x28082040, 0x10240030,
332c5a511f1SSebastian Siewior 	0x02024800, 0x01018000, 0x280020c0, 0x00241030,
333c5a511f1SSebastian Siewior 	0x02024800, 0x01018008, 0x280820c0, 0x10241030,
334c5a511f1SSebastian Siewior 	0x00000c00, 0x04010000, 0x20100000, 0x00000014,
335c5a511f1SSebastian Siewior 	0x00000c00, 0x04010008, 0x20180000, 0x10000014,
336c5a511f1SSebastian Siewior 	0x02000c00, 0x04010000, 0x20100080, 0x00001014,
337c5a511f1SSebastian Siewior 	0x02000c00, 0x04010008, 0x20180080, 0x10001014,
338c5a511f1SSebastian Siewior 	0x00004c00, 0x04010000, 0x20100040, 0x00040014,
339c5a511f1SSebastian Siewior 	0x00004c00, 0x04010008, 0x20180040, 0x10040014,
340c5a511f1SSebastian Siewior 	0x02004c00, 0x04010000, 0x201000c0, 0x00041014,
341c5a511f1SSebastian Siewior 	0x02004c00, 0x04010008, 0x201800c0, 0x10041014,
342c5a511f1SSebastian Siewior 	0x00020c00, 0x04018000, 0x28100000, 0x00200014,
343c5a511f1SSebastian Siewior 	0x00020c00, 0x04018008, 0x28180000, 0x10200014,
344c5a511f1SSebastian Siewior 	0x02020c00, 0x04018000, 0x28100080, 0x00201014,
345c5a511f1SSebastian Siewior 	0x02020c00, 0x04018008, 0x28180080, 0x10201014,
346c5a511f1SSebastian Siewior 	0x00024c00, 0x04018000, 0x28100040, 0x00240014,
347c5a511f1SSebastian Siewior 	0x00024c00, 0x04018008, 0x28180040, 0x10240014,
348c5a511f1SSebastian Siewior 	0x02024c00, 0x04018000, 0x281000c0, 0x00241014,
349c5a511f1SSebastian Siewior 	0x02024c00, 0x04018008, 0x281800c0, 0x10241014,
350c5a511f1SSebastian Siewior 	0x00000c00, 0x05010000, 0x20102000, 0x00000034,
351c5a511f1SSebastian Siewior 	0x00000c00, 0x05010008, 0x20182000, 0x10000034,
352c5a511f1SSebastian Siewior 	0x02000c00, 0x05010000, 0x20102080, 0x00001034,
353c5a511f1SSebastian Siewior 	0x02000c00, 0x05010008, 0x20182080, 0x10001034,
354c5a511f1SSebastian Siewior 	0x00004c00, 0x05010000, 0x20102040, 0x00040034,
355c5a511f1SSebastian Siewior 	0x00004c00, 0x05010008, 0x20182040, 0x10040034,
356c5a511f1SSebastian Siewior 	0x02004c00, 0x05010000, 0x201020c0, 0x00041034,
357c5a511f1SSebastian Siewior 	0x02004c00, 0x05010008, 0x201820c0, 0x10041034,
358c5a511f1SSebastian Siewior 	0x00020c00, 0x05018000, 0x28102000, 0x00200034,
359c5a511f1SSebastian Siewior 	0x00020c00, 0x05018008, 0x28182000, 0x10200034,
360c5a511f1SSebastian Siewior 	0x02020c00, 0x05018000, 0x28102080, 0x00201034,
361c5a511f1SSebastian Siewior 	0x02020c00, 0x05018008, 0x28182080, 0x10201034,
362c5a511f1SSebastian Siewior 	0x00024c00, 0x05018000, 0x28102040, 0x00240034,
363c5a511f1SSebastian Siewior 	0x00024c00, 0x05018008, 0x28182040, 0x10240034,
364c5a511f1SSebastian Siewior 	0x02024c00, 0x05018000, 0x281020c0, 0x00241034,
365c5a511f1SSebastian Siewior 	0x02024c00, 0x05018008, 0x281820c0, 0x10241034
366c5a511f1SSebastian Siewior };
367c5a511f1SSebastian Siewior 
368c5a511f1SSebastian Siewior /* S-box lookup tables */
369c5a511f1SSebastian Siewior 
370c5a511f1SSebastian Siewior static const u32 S1[64] = {
371c5a511f1SSebastian Siewior 	0x01010400, 0x00000000, 0x00010000, 0x01010404,
372c5a511f1SSebastian Siewior 	0x01010004, 0x00010404, 0x00000004, 0x00010000,
373c5a511f1SSebastian Siewior 	0x00000400, 0x01010400, 0x01010404, 0x00000400,
374c5a511f1SSebastian Siewior 	0x01000404, 0x01010004, 0x01000000, 0x00000004,
375c5a511f1SSebastian Siewior 	0x00000404, 0x01000400, 0x01000400, 0x00010400,
376c5a511f1SSebastian Siewior 	0x00010400, 0x01010000, 0x01010000, 0x01000404,
377c5a511f1SSebastian Siewior 	0x00010004, 0x01000004, 0x01000004, 0x00010004,
378c5a511f1SSebastian Siewior 	0x00000000, 0x00000404, 0x00010404, 0x01000000,
379c5a511f1SSebastian Siewior 	0x00010000, 0x01010404, 0x00000004, 0x01010000,
380c5a511f1SSebastian Siewior 	0x01010400, 0x01000000, 0x01000000, 0x00000400,
381c5a511f1SSebastian Siewior 	0x01010004, 0x00010000, 0x00010400, 0x01000004,
382c5a511f1SSebastian Siewior 	0x00000400, 0x00000004, 0x01000404, 0x00010404,
383c5a511f1SSebastian Siewior 	0x01010404, 0x00010004, 0x01010000, 0x01000404,
384c5a511f1SSebastian Siewior 	0x01000004, 0x00000404, 0x00010404, 0x01010400,
385c5a511f1SSebastian Siewior 	0x00000404, 0x01000400, 0x01000400, 0x00000000,
386c5a511f1SSebastian Siewior 	0x00010004, 0x00010400, 0x00000000, 0x01010004
387c5a511f1SSebastian Siewior };
388c5a511f1SSebastian Siewior 
389c5a511f1SSebastian Siewior static const u32 S2[64] = {
390c5a511f1SSebastian Siewior 	0x80108020, 0x80008000, 0x00008000, 0x00108020,
391c5a511f1SSebastian Siewior 	0x00100000, 0x00000020, 0x80100020, 0x80008020,
392c5a511f1SSebastian Siewior 	0x80000020, 0x80108020, 0x80108000, 0x80000000,
393c5a511f1SSebastian Siewior 	0x80008000, 0x00100000, 0x00000020, 0x80100020,
394c5a511f1SSebastian Siewior 	0x00108000, 0x00100020, 0x80008020, 0x00000000,
395c5a511f1SSebastian Siewior 	0x80000000, 0x00008000, 0x00108020, 0x80100000,
396c5a511f1SSebastian Siewior 	0x00100020, 0x80000020, 0x00000000, 0x00108000,
397c5a511f1SSebastian Siewior 	0x00008020, 0x80108000, 0x80100000, 0x00008020,
398c5a511f1SSebastian Siewior 	0x00000000, 0x00108020, 0x80100020, 0x00100000,
399c5a511f1SSebastian Siewior 	0x80008020, 0x80100000, 0x80108000, 0x00008000,
400c5a511f1SSebastian Siewior 	0x80100000, 0x80008000, 0x00000020, 0x80108020,
401c5a511f1SSebastian Siewior 	0x00108020, 0x00000020, 0x00008000, 0x80000000,
402c5a511f1SSebastian Siewior 	0x00008020, 0x80108000, 0x00100000, 0x80000020,
403c5a511f1SSebastian Siewior 	0x00100020, 0x80008020, 0x80000020, 0x00100020,
404c5a511f1SSebastian Siewior 	0x00108000, 0x00000000, 0x80008000, 0x00008020,
405c5a511f1SSebastian Siewior 	0x80000000, 0x80100020, 0x80108020, 0x00108000
406c5a511f1SSebastian Siewior };
407c5a511f1SSebastian Siewior 
408c5a511f1SSebastian Siewior static const u32 S3[64] = {
409c5a511f1SSebastian Siewior 	0x00000208, 0x08020200, 0x00000000, 0x08020008,
410c5a511f1SSebastian Siewior 	0x08000200, 0x00000000, 0x00020208, 0x08000200,
411c5a511f1SSebastian Siewior 	0x00020008, 0x08000008, 0x08000008, 0x00020000,
412c5a511f1SSebastian Siewior 	0x08020208, 0x00020008, 0x08020000, 0x00000208,
413c5a511f1SSebastian Siewior 	0x08000000, 0x00000008, 0x08020200, 0x00000200,
414c5a511f1SSebastian Siewior 	0x00020200, 0x08020000, 0x08020008, 0x00020208,
415c5a511f1SSebastian Siewior 	0x08000208, 0x00020200, 0x00020000, 0x08000208,
416c5a511f1SSebastian Siewior 	0x00000008, 0x08020208, 0x00000200, 0x08000000,
417c5a511f1SSebastian Siewior 	0x08020200, 0x08000000, 0x00020008, 0x00000208,
418c5a511f1SSebastian Siewior 	0x00020000, 0x08020200, 0x08000200, 0x00000000,
419c5a511f1SSebastian Siewior 	0x00000200, 0x00020008, 0x08020208, 0x08000200,
420c5a511f1SSebastian Siewior 	0x08000008, 0x00000200, 0x00000000, 0x08020008,
421c5a511f1SSebastian Siewior 	0x08000208, 0x00020000, 0x08000000, 0x08020208,
422c5a511f1SSebastian Siewior 	0x00000008, 0x00020208, 0x00020200, 0x08000008,
423c5a511f1SSebastian Siewior 	0x08020000, 0x08000208, 0x00000208, 0x08020000,
424c5a511f1SSebastian Siewior 	0x00020208, 0x00000008, 0x08020008, 0x00020200
425c5a511f1SSebastian Siewior };
426c5a511f1SSebastian Siewior 
427c5a511f1SSebastian Siewior static const u32 S4[64] = {
428c5a511f1SSebastian Siewior 	0x00802001, 0x00002081, 0x00002081, 0x00000080,
429c5a511f1SSebastian Siewior 	0x00802080, 0x00800081, 0x00800001, 0x00002001,
430c5a511f1SSebastian Siewior 	0x00000000, 0x00802000, 0x00802000, 0x00802081,
431c5a511f1SSebastian Siewior 	0x00000081, 0x00000000, 0x00800080, 0x00800001,
432c5a511f1SSebastian Siewior 	0x00000001, 0x00002000, 0x00800000, 0x00802001,
433c5a511f1SSebastian Siewior 	0x00000080, 0x00800000, 0x00002001, 0x00002080,
434c5a511f1SSebastian Siewior 	0x00800081, 0x00000001, 0x00002080, 0x00800080,
435c5a511f1SSebastian Siewior 	0x00002000, 0x00802080, 0x00802081, 0x00000081,
436c5a511f1SSebastian Siewior 	0x00800080, 0x00800001, 0x00802000, 0x00802081,
437c5a511f1SSebastian Siewior 	0x00000081, 0x00000000, 0x00000000, 0x00802000,
438c5a511f1SSebastian Siewior 	0x00002080, 0x00800080, 0x00800081, 0x00000001,
439c5a511f1SSebastian Siewior 	0x00802001, 0x00002081, 0x00002081, 0x00000080,
440c5a511f1SSebastian Siewior 	0x00802081, 0x00000081, 0x00000001, 0x00002000,
441c5a511f1SSebastian Siewior 	0x00800001, 0x00002001, 0x00802080, 0x00800081,
442c5a511f1SSebastian Siewior 	0x00002001, 0x00002080, 0x00800000, 0x00802001,
443c5a511f1SSebastian Siewior 	0x00000080, 0x00800000, 0x00002000, 0x00802080
444c5a511f1SSebastian Siewior };
445c5a511f1SSebastian Siewior 
446c5a511f1SSebastian Siewior static const u32 S5[64] = {
447c5a511f1SSebastian Siewior 	0x00000100, 0x02080100, 0x02080000, 0x42000100,
448c5a511f1SSebastian Siewior 	0x00080000, 0x00000100, 0x40000000, 0x02080000,
449c5a511f1SSebastian Siewior 	0x40080100, 0x00080000, 0x02000100, 0x40080100,
450c5a511f1SSebastian Siewior 	0x42000100, 0x42080000, 0x00080100, 0x40000000,
451c5a511f1SSebastian Siewior 	0x02000000, 0x40080000, 0x40080000, 0x00000000,
452c5a511f1SSebastian Siewior 	0x40000100, 0x42080100, 0x42080100, 0x02000100,
453c5a511f1SSebastian Siewior 	0x42080000, 0x40000100, 0x00000000, 0x42000000,
454c5a511f1SSebastian Siewior 	0x02080100, 0x02000000, 0x42000000, 0x00080100,
455c5a511f1SSebastian Siewior 	0x00080000, 0x42000100, 0x00000100, 0x02000000,
456c5a511f1SSebastian Siewior 	0x40000000, 0x02080000, 0x42000100, 0x40080100,
457c5a511f1SSebastian Siewior 	0x02000100, 0x40000000, 0x42080000, 0x02080100,
458c5a511f1SSebastian Siewior 	0x40080100, 0x00000100, 0x02000000, 0x42080000,
459c5a511f1SSebastian Siewior 	0x42080100, 0x00080100, 0x42000000, 0x42080100,
460c5a511f1SSebastian Siewior 	0x02080000, 0x00000000, 0x40080000, 0x42000000,
461c5a511f1SSebastian Siewior 	0x00080100, 0x02000100, 0x40000100, 0x00080000,
462c5a511f1SSebastian Siewior 	0x00000000, 0x40080000, 0x02080100, 0x40000100
463c5a511f1SSebastian Siewior };
464c5a511f1SSebastian Siewior 
465c5a511f1SSebastian Siewior static const u32 S6[64] = {
466c5a511f1SSebastian Siewior 	0x20000010, 0x20400000, 0x00004000, 0x20404010,
467c5a511f1SSebastian Siewior 	0x20400000, 0x00000010, 0x20404010, 0x00400000,
468c5a511f1SSebastian Siewior 	0x20004000, 0x00404010, 0x00400000, 0x20000010,
469c5a511f1SSebastian Siewior 	0x00400010, 0x20004000, 0x20000000, 0x00004010,
470c5a511f1SSebastian Siewior 	0x00000000, 0x00400010, 0x20004010, 0x00004000,
471c5a511f1SSebastian Siewior 	0x00404000, 0x20004010, 0x00000010, 0x20400010,
472c5a511f1SSebastian Siewior 	0x20400010, 0x00000000, 0x00404010, 0x20404000,
473c5a511f1SSebastian Siewior 	0x00004010, 0x00404000, 0x20404000, 0x20000000,
474c5a511f1SSebastian Siewior 	0x20004000, 0x00000010, 0x20400010, 0x00404000,
475c5a511f1SSebastian Siewior 	0x20404010, 0x00400000, 0x00004010, 0x20000010,
476c5a511f1SSebastian Siewior 	0x00400000, 0x20004000, 0x20000000, 0x00004010,
477c5a511f1SSebastian Siewior 	0x20000010, 0x20404010, 0x00404000, 0x20400000,
478c5a511f1SSebastian Siewior 	0x00404010, 0x20404000, 0x00000000, 0x20400010,
479c5a511f1SSebastian Siewior 	0x00000010, 0x00004000, 0x20400000, 0x00404010,
480c5a511f1SSebastian Siewior 	0x00004000, 0x00400010, 0x20004010, 0x00000000,
481c5a511f1SSebastian Siewior 	0x20404000, 0x20000000, 0x00400010, 0x20004010
482c5a511f1SSebastian Siewior };
483c5a511f1SSebastian Siewior 
484c5a511f1SSebastian Siewior static const u32 S7[64] = {
485c5a511f1SSebastian Siewior 	0x00200000, 0x04200002, 0x04000802, 0x00000000,
486c5a511f1SSebastian Siewior 	0x00000800, 0x04000802, 0x00200802, 0x04200800,
487c5a511f1SSebastian Siewior 	0x04200802, 0x00200000, 0x00000000, 0x04000002,
488c5a511f1SSebastian Siewior 	0x00000002, 0x04000000, 0x04200002, 0x00000802,
489c5a511f1SSebastian Siewior 	0x04000800, 0x00200802, 0x00200002, 0x04000800,
490c5a511f1SSebastian Siewior 	0x04000002, 0x04200000, 0x04200800, 0x00200002,
491c5a511f1SSebastian Siewior 	0x04200000, 0x00000800, 0x00000802, 0x04200802,
492c5a511f1SSebastian Siewior 	0x00200800, 0x00000002, 0x04000000, 0x00200800,
493c5a511f1SSebastian Siewior 	0x04000000, 0x00200800, 0x00200000, 0x04000802,
494c5a511f1SSebastian Siewior 	0x04000802, 0x04200002, 0x04200002, 0x00000002,
495c5a511f1SSebastian Siewior 	0x00200002, 0x04000000, 0x04000800, 0x00200000,
496c5a511f1SSebastian Siewior 	0x04200800, 0x00000802, 0x00200802, 0x04200800,
497c5a511f1SSebastian Siewior 	0x00000802, 0x04000002, 0x04200802, 0x04200000,
498c5a511f1SSebastian Siewior 	0x00200800, 0x00000000, 0x00000002, 0x04200802,
499c5a511f1SSebastian Siewior 	0x00000000, 0x00200802, 0x04200000, 0x00000800,
500c5a511f1SSebastian Siewior 	0x04000002, 0x04000800, 0x00000800, 0x00200002
501c5a511f1SSebastian Siewior };
502c5a511f1SSebastian Siewior 
503c5a511f1SSebastian Siewior static const u32 S8[64] = {
504c5a511f1SSebastian Siewior 	0x10001040, 0x00001000, 0x00040000, 0x10041040,
505c5a511f1SSebastian Siewior 	0x10000000, 0x10001040, 0x00000040, 0x10000000,
506c5a511f1SSebastian Siewior 	0x00040040, 0x10040000, 0x10041040, 0x00041000,
507c5a511f1SSebastian Siewior 	0x10041000, 0x00041040, 0x00001000, 0x00000040,
508c5a511f1SSebastian Siewior 	0x10040000, 0x10000040, 0x10001000, 0x00001040,
509c5a511f1SSebastian Siewior 	0x00041000, 0x00040040, 0x10040040, 0x10041000,
510c5a511f1SSebastian Siewior 	0x00001040, 0x00000000, 0x00000000, 0x10040040,
511c5a511f1SSebastian Siewior 	0x10000040, 0x10001000, 0x00041040, 0x00040000,
512c5a511f1SSebastian Siewior 	0x00041040, 0x00040000, 0x10041000, 0x00001000,
513c5a511f1SSebastian Siewior 	0x00000040, 0x10040040, 0x00001000, 0x00041040,
514c5a511f1SSebastian Siewior 	0x10001000, 0x00000040, 0x10000040, 0x10040000,
515c5a511f1SSebastian Siewior 	0x10040040, 0x10000000, 0x00040000, 0x10001040,
516c5a511f1SSebastian Siewior 	0x00000000, 0x10041040, 0x00040040, 0x10000040,
517c5a511f1SSebastian Siewior 	0x10040000, 0x10001000, 0x10001040, 0x00000000,
518c5a511f1SSebastian Siewior 	0x10041040, 0x00041000, 0x00041000, 0x00001040,
519c5a511f1SSebastian Siewior 	0x00001040, 0x00040040, 0x10000000, 0x10041000
520c5a511f1SSebastian Siewior };
521c5a511f1SSebastian Siewior 
522c5a511f1SSebastian Siewior /* Encryption components: IP, FP, and round function */
523c5a511f1SSebastian Siewior 
524c5a511f1SSebastian Siewior #define IP(L, R, T)		\
525c5a511f1SSebastian Siewior 	ROL(R, 4);		\
526c5a511f1SSebastian Siewior 	T  = L;			\
527c5a511f1SSebastian Siewior 	L ^= R;			\
528c5a511f1SSebastian Siewior 	L &= 0xf0f0f0f0;	\
529c5a511f1SSebastian Siewior 	R ^= L;			\
530c5a511f1SSebastian Siewior 	L ^= T;			\
531c5a511f1SSebastian Siewior 	ROL(R, 12);		\
532c5a511f1SSebastian Siewior 	T  = L;			\
533c5a511f1SSebastian Siewior 	L ^= R;			\
534c5a511f1SSebastian Siewior 	L &= 0xffff0000;	\
535c5a511f1SSebastian Siewior 	R ^= L;			\
536c5a511f1SSebastian Siewior 	L ^= T;			\
537c5a511f1SSebastian Siewior 	ROR(R, 14);		\
538c5a511f1SSebastian Siewior 	T  = L;			\
539c5a511f1SSebastian Siewior 	L ^= R;			\
540c5a511f1SSebastian Siewior 	L &= 0xcccccccc;	\
541c5a511f1SSebastian Siewior 	R ^= L;			\
542c5a511f1SSebastian Siewior 	L ^= T;			\
543c5a511f1SSebastian Siewior 	ROL(R, 6);		\
544c5a511f1SSebastian Siewior 	T  = L;			\
545c5a511f1SSebastian Siewior 	L ^= R;			\
546c5a511f1SSebastian Siewior 	L &= 0xff00ff00;	\
547c5a511f1SSebastian Siewior 	R ^= L;			\
548c5a511f1SSebastian Siewior 	L ^= T;			\
549c5a511f1SSebastian Siewior 	ROR(R, 7);		\
550c5a511f1SSebastian Siewior 	T  = L;			\
551c5a511f1SSebastian Siewior 	L ^= R;			\
552c5a511f1SSebastian Siewior 	L &= 0xaaaaaaaa;	\
553c5a511f1SSebastian Siewior 	R ^= L;			\
554c5a511f1SSebastian Siewior 	L ^= T;			\
555c5a511f1SSebastian Siewior 	ROL(L, 1);
556c5a511f1SSebastian Siewior 
557c5a511f1SSebastian Siewior #define FP(L, R, T)		\
558c5a511f1SSebastian Siewior 	ROR(L, 1);		\
559c5a511f1SSebastian Siewior 	T  = L;			\
560c5a511f1SSebastian Siewior 	L ^= R;			\
561c5a511f1SSebastian Siewior 	L &= 0xaaaaaaaa;	\
562c5a511f1SSebastian Siewior 	R ^= L;			\
563c5a511f1SSebastian Siewior 	L ^= T;			\
564c5a511f1SSebastian Siewior 	ROL(R, 7);		\
565c5a511f1SSebastian Siewior 	T  = L;			\
566c5a511f1SSebastian Siewior 	L ^= R;			\
567c5a511f1SSebastian Siewior 	L &= 0xff00ff00;	\
568c5a511f1SSebastian Siewior 	R ^= L;			\
569c5a511f1SSebastian Siewior 	L ^= T;			\
570c5a511f1SSebastian Siewior 	ROR(R, 6);		\
571c5a511f1SSebastian Siewior 	T  = L;			\
572c5a511f1SSebastian Siewior 	L ^= R;			\
573c5a511f1SSebastian Siewior 	L &= 0xcccccccc;	\
574c5a511f1SSebastian Siewior 	R ^= L;			\
575c5a511f1SSebastian Siewior 	L ^= T;			\
576c5a511f1SSebastian Siewior 	ROL(R, 14);		\
577c5a511f1SSebastian Siewior 	T  = L;			\
578c5a511f1SSebastian Siewior 	L ^= R;			\
579c5a511f1SSebastian Siewior 	L &= 0xffff0000;	\
580c5a511f1SSebastian Siewior 	R ^= L;			\
581c5a511f1SSebastian Siewior 	L ^= T;			\
582c5a511f1SSebastian Siewior 	ROR(R, 12);		\
583c5a511f1SSebastian Siewior 	T  = L;			\
584c5a511f1SSebastian Siewior 	L ^= R;			\
585c5a511f1SSebastian Siewior 	L &= 0xf0f0f0f0;	\
586c5a511f1SSebastian Siewior 	R ^= L;			\
587c5a511f1SSebastian Siewior 	L ^= T;			\
588c5a511f1SSebastian Siewior 	ROR(R, 4);
589c5a511f1SSebastian Siewior 
590c5a511f1SSebastian Siewior #define ROUND(L, R, A, B, K, d)					\
591c5a511f1SSebastian Siewior 	B = K[0];			A = K[1];	K += d;	\
592c5a511f1SSebastian Siewior 	B ^= R;				A ^= R;			\
593c5a511f1SSebastian Siewior 	B &= 0x3f3f3f3f;		ROR(A, 4);		\
594c5a511f1SSebastian Siewior 	L ^= S8[0xff & B];		A &= 0x3f3f3f3f;	\
595c5a511f1SSebastian Siewior 	L ^= S6[0xff & (B >> 8)];	B >>= 16;		\
596c5a511f1SSebastian Siewior 	L ^= S7[0xff & A];					\
597c5a511f1SSebastian Siewior 	L ^= S5[0xff & (A >> 8)];	A >>= 16;		\
598c5a511f1SSebastian Siewior 	L ^= S4[0xff & B];					\
599c5a511f1SSebastian Siewior 	L ^= S2[0xff & (B >> 8)];				\
600c5a511f1SSebastian Siewior 	L ^= S3[0xff & A];					\
601c5a511f1SSebastian Siewior 	L ^= S1[0xff & (A >> 8)];
602c5a511f1SSebastian Siewior 
603c5a511f1SSebastian Siewior /*
604c5a511f1SSebastian Siewior  * PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved
605c5a511f1SSebastian Siewior  * tables of 128 elements.  One set is for C_i and the other for D_i, while
606c5a511f1SSebastian Siewior  * the 4 interleaved tables correspond to four 7-bit subsets of C_i or D_i.
607c5a511f1SSebastian Siewior  *
608c5a511f1SSebastian Siewior  * After PC1 each of the variables a,b,c,d contains a 7 bit subset of C_i
609c5a511f1SSebastian Siewior  * or D_i in bits 7-1 (bit 0 being the least significant).
610c5a511f1SSebastian Siewior  */
611c5a511f1SSebastian Siewior 
612c5a511f1SSebastian Siewior #define T1(x) pt[2 * (x) + 0]
613c5a511f1SSebastian Siewior #define T2(x) pt[2 * (x) + 1]
614c5a511f1SSebastian Siewior #define T3(x) pt[2 * (x) + 2]
615c5a511f1SSebastian Siewior #define T4(x) pt[2 * (x) + 3]
616c5a511f1SSebastian Siewior 
617c5a511f1SSebastian Siewior #define PC2(a, b, c, d) (T4(d) | T3(c) | T2(b) | T1(a))
618c5a511f1SSebastian Siewior 
619c5a511f1SSebastian Siewior /*
620c5a511f1SSebastian Siewior  * Encryption key expansion
621c5a511f1SSebastian Siewior  *
622c5a511f1SSebastian Siewior  * RFC2451: Weak key checks SHOULD be performed.
623c5a511f1SSebastian Siewior  *
624c5a511f1SSebastian Siewior  * FIPS 74:
625c5a511f1SSebastian Siewior  *
626c5a511f1SSebastian Siewior  *   Keys having duals are keys which produce all zeros, all ones, or
627c5a511f1SSebastian Siewior  *   alternating zero-one patterns in the C and D registers after Permuted
628c5a511f1SSebastian Siewior  *   Choice 1 has operated on the key.
629c5a511f1SSebastian Siewior  *
630c5a511f1SSebastian Siewior  */
631c5a511f1SSebastian Siewior static unsigned long ekey(u32 *pe, const u8 *k)
632c5a511f1SSebastian Siewior {
633c5a511f1SSebastian Siewior 	/* K&R: long is at least 32 bits */
634c5a511f1SSebastian Siewior 	unsigned long a, b, c, d, w;
635c5a511f1SSebastian Siewior 	const u32 *pt = pc2;
636c5a511f1SSebastian Siewior 
637c5a511f1SSebastian Siewior 	d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
638c5a511f1SSebastian Siewior 	c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
639c5a511f1SSebastian Siewior 	b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
640c5a511f1SSebastian Siewior 	a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
641c5a511f1SSebastian Siewior 
642c5a511f1SSebastian Siewior 	pe[15 * 2 + 0] = PC2(a, b, c, d); d = rs[d];
643c5a511f1SSebastian Siewior 	pe[14 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
644c5a511f1SSebastian Siewior 	pe[13 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
645c5a511f1SSebastian Siewior 	pe[12 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
646c5a511f1SSebastian Siewior 	pe[11 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
647c5a511f1SSebastian Siewior 	pe[10 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
648c5a511f1SSebastian Siewior 	pe[ 9 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
649c5a511f1SSebastian Siewior 	pe[ 8 * 2 + 0] = PC2(d, a, b, c); c = rs[c];
650c5a511f1SSebastian Siewior 	pe[ 7 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
651c5a511f1SSebastian Siewior 	pe[ 6 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
652c5a511f1SSebastian Siewior 	pe[ 5 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
653c5a511f1SSebastian Siewior 	pe[ 4 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
654c5a511f1SSebastian Siewior 	pe[ 3 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
655c5a511f1SSebastian Siewior 	pe[ 2 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
656c5a511f1SSebastian Siewior 	pe[ 1 * 2 + 0] = PC2(c, d, a, b); b = rs[b];
657c5a511f1SSebastian Siewior 	pe[ 0 * 2 + 0] = PC2(b, c, d, a);
658c5a511f1SSebastian Siewior 
659c5a511f1SSebastian Siewior 	/* Check if first half is weak */
660c5a511f1SSebastian Siewior 	w  = (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
661c5a511f1SSebastian Siewior 
662c5a511f1SSebastian Siewior 	/* Skip to next table set */
663c5a511f1SSebastian Siewior 	pt += 512;
664c5a511f1SSebastian Siewior 
665c5a511f1SSebastian Siewior 	d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
666c5a511f1SSebastian Siewior 	c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
667c5a511f1SSebastian Siewior 	b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
668c5a511f1SSebastian Siewior 	a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
669c5a511f1SSebastian Siewior 
670c5a511f1SSebastian Siewior 	/* Check if second half is weak */
671c5a511f1SSebastian Siewior 	w |= (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
672c5a511f1SSebastian Siewior 
673c5a511f1SSebastian Siewior 	pe[15 * 2 + 1] = PC2(a, b, c, d); d = rs[d];
674c5a511f1SSebastian Siewior 	pe[14 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
675c5a511f1SSebastian Siewior 	pe[13 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
676c5a511f1SSebastian Siewior 	pe[12 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
677c5a511f1SSebastian Siewior 	pe[11 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
678c5a511f1SSebastian Siewior 	pe[10 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
679c5a511f1SSebastian Siewior 	pe[ 9 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
680c5a511f1SSebastian Siewior 	pe[ 8 * 2 + 1] = PC2(d, a, b, c); c = rs[c];
681c5a511f1SSebastian Siewior 	pe[ 7 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
682c5a511f1SSebastian Siewior 	pe[ 6 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
683c5a511f1SSebastian Siewior 	pe[ 5 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
684c5a511f1SSebastian Siewior 	pe[ 4 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
685c5a511f1SSebastian Siewior 	pe[ 3 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
686c5a511f1SSebastian Siewior 	pe[ 2 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
687c5a511f1SSebastian Siewior 	pe[ 1 * 2 + 1] = PC2(c, d, a, b); b = rs[b];
688c5a511f1SSebastian Siewior 	pe[ 0 * 2 + 1] = PC2(b, c, d, a);
689c5a511f1SSebastian Siewior 
690c5a511f1SSebastian Siewior 	/* Fixup: 2413 5768 -> 1357 2468 */
691c5a511f1SSebastian Siewior 	for (d = 0; d < 16; ++d) {
692c5a511f1SSebastian Siewior 		a = pe[2 * d];
693c5a511f1SSebastian Siewior 		b = pe[2 * d + 1];
694c5a511f1SSebastian Siewior 		c = a ^ b;
695c5a511f1SSebastian Siewior 		c &= 0xffff0000;
696c5a511f1SSebastian Siewior 		a ^= c;
697c5a511f1SSebastian Siewior 		b ^= c;
698c5a511f1SSebastian Siewior 		ROL(b, 18);
699c5a511f1SSebastian Siewior 		pe[2 * d] = a;
700c5a511f1SSebastian Siewior 		pe[2 * d + 1] = b;
701c5a511f1SSebastian Siewior 	}
702c5a511f1SSebastian Siewior 
703c5a511f1SSebastian Siewior 	/* Zero if weak key */
704c5a511f1SSebastian Siewior 	return w;
705c5a511f1SSebastian Siewior }
706c5a511f1SSebastian Siewior 
707c5a511f1SSebastian Siewior /*
708c5a511f1SSebastian Siewior  * Decryption key expansion
709c5a511f1SSebastian Siewior  *
710c5a511f1SSebastian Siewior  * No weak key checking is performed, as this is only used by triple DES
711c5a511f1SSebastian Siewior  *
712c5a511f1SSebastian Siewior  */
713c5a511f1SSebastian Siewior static void dkey(u32 *pe, const u8 *k)
714c5a511f1SSebastian Siewior {
715c5a511f1SSebastian Siewior 	/* K&R: long is at least 32 bits */
716c5a511f1SSebastian Siewior 	unsigned long a, b, c, d;
717c5a511f1SSebastian Siewior 	const u32 *pt = pc2;
718c5a511f1SSebastian Siewior 
719c5a511f1SSebastian Siewior 	d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
720c5a511f1SSebastian Siewior 	c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
721c5a511f1SSebastian Siewior 	b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
722c5a511f1SSebastian Siewior 	a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
723c5a511f1SSebastian Siewior 
724c5a511f1SSebastian Siewior 	pe[ 0 * 2] = PC2(a, b, c, d); d = rs[d];
725c5a511f1SSebastian Siewior 	pe[ 1 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
726c5a511f1SSebastian Siewior 	pe[ 2 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
727c5a511f1SSebastian Siewior 	pe[ 3 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
728c5a511f1SSebastian Siewior 	pe[ 4 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
729c5a511f1SSebastian Siewior 	pe[ 5 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
730c5a511f1SSebastian Siewior 	pe[ 6 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
731c5a511f1SSebastian Siewior 	pe[ 7 * 2] = PC2(d, a, b, c); c = rs[c];
732c5a511f1SSebastian Siewior 	pe[ 8 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
733c5a511f1SSebastian Siewior 	pe[ 9 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
734c5a511f1SSebastian Siewior 	pe[10 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
735c5a511f1SSebastian Siewior 	pe[11 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
736c5a511f1SSebastian Siewior 	pe[12 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
737c5a511f1SSebastian Siewior 	pe[13 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
738c5a511f1SSebastian Siewior 	pe[14 * 2] = PC2(c, d, a, b); b = rs[b];
739c5a511f1SSebastian Siewior 	pe[15 * 2] = PC2(b, c, d, a);
740c5a511f1SSebastian Siewior 
741c5a511f1SSebastian Siewior 	/* Skip to next table set */
742c5a511f1SSebastian Siewior 	pt += 512;
743c5a511f1SSebastian Siewior 
744c5a511f1SSebastian Siewior 	d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
745c5a511f1SSebastian Siewior 	c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
746c5a511f1SSebastian Siewior 	b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
747c5a511f1SSebastian Siewior 	a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
748c5a511f1SSebastian Siewior 
749c5a511f1SSebastian Siewior 	pe[ 0 * 2 + 1] = PC2(a, b, c, d); d = rs[d];
750c5a511f1SSebastian Siewior 	pe[ 1 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
751c5a511f1SSebastian Siewior 	pe[ 2 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
752c5a511f1SSebastian Siewior 	pe[ 3 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
753c5a511f1SSebastian Siewior 	pe[ 4 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
754c5a511f1SSebastian Siewior 	pe[ 5 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
755c5a511f1SSebastian Siewior 	pe[ 6 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
756c5a511f1SSebastian Siewior 	pe[ 7 * 2 + 1] = PC2(d, a, b, c); c = rs[c];
757c5a511f1SSebastian Siewior 	pe[ 8 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
758c5a511f1SSebastian Siewior 	pe[ 9 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
759c5a511f1SSebastian Siewior 	pe[10 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
760c5a511f1SSebastian Siewior 	pe[11 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
761c5a511f1SSebastian Siewior 	pe[12 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
762c5a511f1SSebastian Siewior 	pe[13 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
763c5a511f1SSebastian Siewior 	pe[14 * 2 + 1] = PC2(c, d, a, b); b = rs[b];
764c5a511f1SSebastian Siewior 	pe[15 * 2 + 1] = PC2(b, c, d, a);
765c5a511f1SSebastian Siewior 
766c5a511f1SSebastian Siewior 	/* Fixup: 2413 5768 -> 1357 2468 */
767c5a511f1SSebastian Siewior 	for (d = 0; d < 16; ++d) {
768c5a511f1SSebastian Siewior 		a = pe[2 * d];
769c5a511f1SSebastian Siewior 		b = pe[2 * d + 1];
770c5a511f1SSebastian Siewior 		c = a ^ b;
771c5a511f1SSebastian Siewior 		c &= 0xffff0000;
772c5a511f1SSebastian Siewior 		a ^= c;
773c5a511f1SSebastian Siewior 		b ^= c;
774c5a511f1SSebastian Siewior 		ROL(b, 18);
775c5a511f1SSebastian Siewior 		pe[2 * d] = a;
776c5a511f1SSebastian Siewior 		pe[2 * d + 1] = b;
777c5a511f1SSebastian Siewior 	}
778c5a511f1SSebastian Siewior }
779c5a511f1SSebastian Siewior 
780c5a511f1SSebastian Siewior static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
781c5a511f1SSebastian Siewior 		      unsigned int keylen)
782c5a511f1SSebastian Siewior {
783c5a511f1SSebastian Siewior 	struct des_ctx *dctx = crypto_tfm_ctx(tfm);
784c5a511f1SSebastian Siewior 	u32 *flags = &tfm->crt_flags;
785c5a511f1SSebastian Siewior 	u32 tmp[DES_EXPKEY_WORDS];
786c5a511f1SSebastian Siewior 	int ret;
787c5a511f1SSebastian Siewior 
788c5a511f1SSebastian Siewior 	/* Expand to tmp */
789c5a511f1SSebastian Siewior 	ret = ekey(tmp, key);
790c5a511f1SSebastian Siewior 
791c5a511f1SSebastian Siewior 	if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
792c5a511f1SSebastian Siewior 		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
793c5a511f1SSebastian Siewior 		return -EINVAL;
794c5a511f1SSebastian Siewior 	}
795c5a511f1SSebastian Siewior 
796c5a511f1SSebastian Siewior 	/* Copy to output */
797c5a511f1SSebastian Siewior 	memcpy(dctx->expkey, tmp, sizeof(dctx->expkey));
798c5a511f1SSebastian Siewior 
799c5a511f1SSebastian Siewior 	return 0;
800c5a511f1SSebastian Siewior }
801c5a511f1SSebastian Siewior 
802c5a511f1SSebastian Siewior static void des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
803c5a511f1SSebastian Siewior {
804c5a511f1SSebastian Siewior 	struct des_ctx *ctx = crypto_tfm_ctx(tfm);
805c5a511f1SSebastian Siewior 	const u32 *K = ctx->expkey;
806c5a511f1SSebastian Siewior 	const __le32 *s = (const __le32 *)src;
807c5a511f1SSebastian Siewior 	__le32 *d = (__le32 *)dst;
808c5a511f1SSebastian Siewior 	u32 L, R, A, B;
809c5a511f1SSebastian Siewior 	int i;
810c5a511f1SSebastian Siewior 
811c5a511f1SSebastian Siewior 	L = le32_to_cpu(s[0]);
812c5a511f1SSebastian Siewior 	R = le32_to_cpu(s[1]);
813c5a511f1SSebastian Siewior 
814c5a511f1SSebastian Siewior 	IP(L, R, A);
815c5a511f1SSebastian Siewior 	for (i = 0; i < 8; i++) {
816c5a511f1SSebastian Siewior 		ROUND(L, R, A, B, K, 2);
817c5a511f1SSebastian Siewior 		ROUND(R, L, A, B, K, 2);
818c5a511f1SSebastian Siewior 	}
819c5a511f1SSebastian Siewior 	FP(R, L, A);
820c5a511f1SSebastian Siewior 
821c5a511f1SSebastian Siewior 	d[0] = cpu_to_le32(R);
822c5a511f1SSebastian Siewior 	d[1] = cpu_to_le32(L);
823c5a511f1SSebastian Siewior }
824c5a511f1SSebastian Siewior 
825c5a511f1SSebastian Siewior static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
826c5a511f1SSebastian Siewior {
827c5a511f1SSebastian Siewior 	struct des_ctx *ctx = crypto_tfm_ctx(tfm);
828c5a511f1SSebastian Siewior 	const u32 *K = ctx->expkey + DES_EXPKEY_WORDS - 2;
829c5a511f1SSebastian Siewior 	const __le32 *s = (const __le32 *)src;
830c5a511f1SSebastian Siewior 	__le32 *d = (__le32 *)dst;
831c5a511f1SSebastian Siewior 	u32 L, R, A, B;
832c5a511f1SSebastian Siewior 	int i;
833c5a511f1SSebastian Siewior 
834c5a511f1SSebastian Siewior 	L = le32_to_cpu(s[0]);
835c5a511f1SSebastian Siewior 	R = le32_to_cpu(s[1]);
836c5a511f1SSebastian Siewior 
837c5a511f1SSebastian Siewior 	IP(L, R, A);
838c5a511f1SSebastian Siewior 	for (i = 0; i < 8; i++) {
839c5a511f1SSebastian Siewior 		ROUND(L, R, A, B, K, -2);
840c5a511f1SSebastian Siewior 		ROUND(R, L, A, B, K, -2);
841c5a511f1SSebastian Siewior 	}
842c5a511f1SSebastian Siewior 	FP(R, L, A);
843c5a511f1SSebastian Siewior 
844c5a511f1SSebastian Siewior 	d[0] = cpu_to_le32(R);
845c5a511f1SSebastian Siewior 	d[1] = cpu_to_le32(L);
846c5a511f1SSebastian Siewior }
847c5a511f1SSebastian Siewior 
848c5a511f1SSebastian Siewior /*
849c5a511f1SSebastian Siewior  * RFC2451:
850c5a511f1SSebastian Siewior  *
851c5a511f1SSebastian Siewior  *   For DES-EDE3, there is no known need to reject weak or
852c5a511f1SSebastian Siewior  *   complementation keys.  Any weakness is obviated by the use of
853c5a511f1SSebastian Siewior  *   multiple keys.
854c5a511f1SSebastian Siewior  *
855c5a511f1SSebastian Siewior  *   However, if the first two or last two independent 64-bit keys are
856c5a511f1SSebastian Siewior  *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
857c5a511f1SSebastian Siewior  *   same as DES.  Implementers MUST reject keys that exhibit this
858c5a511f1SSebastian Siewior  *   property.
859c5a511f1SSebastian Siewior  *
860c5a511f1SSebastian Siewior  */
861c5a511f1SSebastian Siewior static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
862c5a511f1SSebastian Siewior 			   unsigned int keylen)
863c5a511f1SSebastian Siewior {
864c5a511f1SSebastian Siewior 	const u32 *K = (const u32 *)key;
865c5a511f1SSebastian Siewior 	struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
866c5a511f1SSebastian Siewior 	u32 *expkey = dctx->expkey;
867c5a511f1SSebastian Siewior 	u32 *flags = &tfm->crt_flags;
868c5a511f1SSebastian Siewior 
869c5a511f1SSebastian Siewior 	if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
870c5a511f1SSebastian Siewior 		     !((K[2] ^ K[4]) | (K[3] ^ K[5]))))
871c5a511f1SSebastian Siewior 	{
872c5a511f1SSebastian Siewior 		*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
873c5a511f1SSebastian Siewior 		return -EINVAL;
874c5a511f1SSebastian Siewior 	}
875c5a511f1SSebastian Siewior 
876c5a511f1SSebastian Siewior 	ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
877c5a511f1SSebastian Siewior 	dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
878c5a511f1SSebastian Siewior 	ekey(expkey, key);
879c5a511f1SSebastian Siewior 
880c5a511f1SSebastian Siewior 	return 0;
881c5a511f1SSebastian Siewior }
882c5a511f1SSebastian Siewior 
883c5a511f1SSebastian Siewior static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
884c5a511f1SSebastian Siewior {
885c5a511f1SSebastian Siewior 	struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
886c5a511f1SSebastian Siewior 	const u32 *K = dctx->expkey;
887c5a511f1SSebastian Siewior 	const __le32 *s = (const __le32 *)src;
888c5a511f1SSebastian Siewior 	__le32 *d = (__le32 *)dst;
889c5a511f1SSebastian Siewior 	u32 L, R, A, B;
890c5a511f1SSebastian Siewior 	int i;
891c5a511f1SSebastian Siewior 
892c5a511f1SSebastian Siewior 	L = le32_to_cpu(s[0]);
893c5a511f1SSebastian Siewior 	R = le32_to_cpu(s[1]);
894c5a511f1SSebastian Siewior 
895c5a511f1SSebastian Siewior 	IP(L, R, A);
896c5a511f1SSebastian Siewior 	for (i = 0; i < 8; i++) {
897c5a511f1SSebastian Siewior 		ROUND(L, R, A, B, K, 2);
898c5a511f1SSebastian Siewior 		ROUND(R, L, A, B, K, 2);
899c5a511f1SSebastian Siewior 	}
900c5a511f1SSebastian Siewior 	for (i = 0; i < 8; i++) {
901c5a511f1SSebastian Siewior 		ROUND(R, L, A, B, K, 2);
902c5a511f1SSebastian Siewior 		ROUND(L, R, A, B, K, 2);
903c5a511f1SSebastian Siewior 	}
904c5a511f1SSebastian Siewior 	for (i = 0; i < 8; i++) {
905c5a511f1SSebastian Siewior 		ROUND(L, R, A, B, K, 2);
906c5a511f1SSebastian Siewior 		ROUND(R, L, A, B, K, 2);
907c5a511f1SSebastian Siewior 	}
908c5a511f1SSebastian Siewior 	FP(R, L, A);
909c5a511f1SSebastian Siewior 
910c5a511f1SSebastian Siewior 	d[0] = cpu_to_le32(R);
911c5a511f1SSebastian Siewior 	d[1] = cpu_to_le32(L);
912c5a511f1SSebastian Siewior }
913c5a511f1SSebastian Siewior 
914c5a511f1SSebastian Siewior static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
915c5a511f1SSebastian Siewior {
916c5a511f1SSebastian Siewior 	struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
917c5a511f1SSebastian Siewior 	const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2;
918c5a511f1SSebastian Siewior 	const __le32 *s = (const __le32 *)src;
919c5a511f1SSebastian Siewior 	__le32 *d = (__le32 *)dst;
920c5a511f1SSebastian Siewior 	u32 L, R, A, B;
921c5a511f1SSebastian Siewior 	int i;
922c5a511f1SSebastian Siewior 
923c5a511f1SSebastian Siewior 	L = le32_to_cpu(s[0]);
924c5a511f1SSebastian Siewior 	R = le32_to_cpu(s[1]);
925c5a511f1SSebastian Siewior 
926c5a511f1SSebastian Siewior 	IP(L, R, A);
927c5a511f1SSebastian Siewior 	for (i = 0; i < 8; i++) {
928c5a511f1SSebastian Siewior 		ROUND(L, R, A, B, K, -2);
929c5a511f1SSebastian Siewior 		ROUND(R, L, A, B, K, -2);
930c5a511f1SSebastian Siewior 	}
931c5a511f1SSebastian Siewior 	for (i = 0; i < 8; i++) {
932c5a511f1SSebastian Siewior 		ROUND(R, L, A, B, K, -2);
933c5a511f1SSebastian Siewior 		ROUND(L, R, A, B, K, -2);
934c5a511f1SSebastian Siewior 	}
935c5a511f1SSebastian Siewior 	for (i = 0; i < 8; i++) {
936c5a511f1SSebastian Siewior 		ROUND(L, R, A, B, K, -2);
937c5a511f1SSebastian Siewior 		ROUND(R, L, A, B, K, -2);
938c5a511f1SSebastian Siewior 	}
939c5a511f1SSebastian Siewior 	FP(R, L, A);
940c5a511f1SSebastian Siewior 
941c5a511f1SSebastian Siewior 	d[0] = cpu_to_le32(R);
942c5a511f1SSebastian Siewior 	d[1] = cpu_to_le32(L);
943c5a511f1SSebastian Siewior }
944c5a511f1SSebastian Siewior 
945c5a511f1SSebastian Siewior static struct crypto_alg des_alg = {
946c5a511f1SSebastian Siewior 	.cra_name		=	"des",
947c5a511f1SSebastian Siewior 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
948c5a511f1SSebastian Siewior 	.cra_blocksize		=	DES_BLOCK_SIZE,
949c5a511f1SSebastian Siewior 	.cra_ctxsize		=	sizeof(struct des_ctx),
950c5a511f1SSebastian Siewior 	.cra_module		=	THIS_MODULE,
951c5a511f1SSebastian Siewior 	.cra_alignmask		=	3,
952c5a511f1SSebastian Siewior 	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
953c5a511f1SSebastian Siewior 	.cra_u			=	{ .cipher = {
954c5a511f1SSebastian Siewior 	.cia_min_keysize	=	DES_KEY_SIZE,
955c5a511f1SSebastian Siewior 	.cia_max_keysize	=	DES_KEY_SIZE,
956c5a511f1SSebastian Siewior 	.cia_setkey		=	des_setkey,
957c5a511f1SSebastian Siewior 	.cia_encrypt		=	des_encrypt,
958c5a511f1SSebastian Siewior 	.cia_decrypt		=	des_decrypt } }
959c5a511f1SSebastian Siewior };
960c5a511f1SSebastian Siewior 
961c5a511f1SSebastian Siewior static struct crypto_alg des3_ede_alg = {
962c5a511f1SSebastian Siewior 	.cra_name		=	"des3_ede",
963c5a511f1SSebastian Siewior 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
964c5a511f1SSebastian Siewior 	.cra_blocksize		=	DES3_EDE_BLOCK_SIZE,
965c5a511f1SSebastian Siewior 	.cra_ctxsize		=	sizeof(struct des3_ede_ctx),
966c5a511f1SSebastian Siewior 	.cra_module		=	THIS_MODULE,
967c5a511f1SSebastian Siewior 	.cra_alignmask		=	3,
968c5a511f1SSebastian Siewior 	.cra_list		=	LIST_HEAD_INIT(des3_ede_alg.cra_list),
969c5a511f1SSebastian Siewior 	.cra_u			=	{ .cipher = {
970c5a511f1SSebastian Siewior 	.cia_min_keysize	=	DES3_EDE_KEY_SIZE,
971c5a511f1SSebastian Siewior 	.cia_max_keysize	=	DES3_EDE_KEY_SIZE,
972c5a511f1SSebastian Siewior 	.cia_setkey		=	des3_ede_setkey,
973c5a511f1SSebastian Siewior 	.cia_encrypt		=	des3_ede_encrypt,
974c5a511f1SSebastian Siewior 	.cia_decrypt		=	des3_ede_decrypt } }
975c5a511f1SSebastian Siewior };
976c5a511f1SSebastian Siewior 
977c5a511f1SSebastian Siewior MODULE_ALIAS("des3_ede");
978c5a511f1SSebastian Siewior 
979c5a511f1SSebastian Siewior static int __init init(void)
980c5a511f1SSebastian Siewior {
981c5a511f1SSebastian Siewior 	int ret = 0;
982c5a511f1SSebastian Siewior 
983c5a511f1SSebastian Siewior 	ret = crypto_register_alg(&des_alg);
984c5a511f1SSebastian Siewior 	if (ret < 0)
985c5a511f1SSebastian Siewior 		goto out;
986c5a511f1SSebastian Siewior 
987c5a511f1SSebastian Siewior 	ret = crypto_register_alg(&des3_ede_alg);
988c5a511f1SSebastian Siewior 	if (ret < 0)
989c5a511f1SSebastian Siewior 		crypto_unregister_alg(&des_alg);
990c5a511f1SSebastian Siewior out:
991c5a511f1SSebastian Siewior 	return ret;
992c5a511f1SSebastian Siewior }
993c5a511f1SSebastian Siewior 
994c5a511f1SSebastian Siewior static void __exit fini(void)
995c5a511f1SSebastian Siewior {
996c5a511f1SSebastian Siewior 	crypto_unregister_alg(&des3_ede_alg);
997c5a511f1SSebastian Siewior 	crypto_unregister_alg(&des_alg);
998c5a511f1SSebastian Siewior }
999c5a511f1SSebastian Siewior 
1000c5a511f1SSebastian Siewior module_init(init);
1001c5a511f1SSebastian Siewior module_exit(fini);
1002c5a511f1SSebastian Siewior 
1003c5a511f1SSebastian Siewior MODULE_LICENSE("GPL");
1004c5a511f1SSebastian Siewior MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
1005c5a511f1SSebastian Siewior MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>");
1006c5a511f1SSebastian Siewior MODULE_ALIAS("des");
1007