xref: /linux/crypto/seed.c (revision 24bce201d79807b668bf9d9e0aca801c5c0d5f78)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Cryptographic API.
4  *
5  * SEED Cipher Algorithm.
6  *
7  * Documentation of SEED can be found in RFC 4269.
8  * Copyright (C) 2007 Korea Information Security Agency (KISA).
9  */
10 
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/types.h>
14 #include <linux/errno.h>
15 #include <linux/crypto.h>
16 #include <asm/byteorder.h>
17 
18 #define SEED_NUM_KCONSTANTS	16
19 #define SEED_KEY_SIZE		16
20 #define SEED_BLOCK_SIZE		16
21 #define SEED_KEYSCHED_LEN	32
22 
23 /*
24  * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
25  */
26 static inline u8
27 byte(const u32 x, const unsigned n)
28 {
29 	return x >> (n << 3);
30 }
31 
32 struct seed_ctx {
33 	u32 keysched[SEED_KEYSCHED_LEN];
34 };
35 
36 static const u32 SS0[256] = {
37 	0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0,
38 	0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
39 	0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
40 	0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
41 	0x28082028, 0x04444044, 0x20002020, 0x1d8d919c,
42 	0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
43 	0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378,
44 	0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
45 	0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
46 	0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
47 	0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354,
48 	0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
49 	0x24042024, 0x1c0c101c, 0x33437370, 0x18889098,
50 	0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
51 	0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
52 	0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
53 	0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8,
54 	0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
55 	0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078,
56 	0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
57 	0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
58 	0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
59 	0x1f0f131c, 0x19899198, 0x00000000, 0x19091118,
60 	0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
61 	0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324,
62 	0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
63 	0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
64 	0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
65 	0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4,
66 	0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
67 	0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218,
68 	0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
69 	0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
70 	0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
71 	0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4,
72 	0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
73 	0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac,
74 	0x36063234, 0x15051114, 0x22022220, 0x38083038,
75 	0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
76 	0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
77 	0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c,
78 	0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
79 	0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8,
80 	0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
81 	0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
82 	0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
83 	0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320,
84 	0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
85 	0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0,
86 	0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
87 	0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
88 	0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
89 	0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c,
90 	0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
91 	0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244,
92 	0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
93 	0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
94 	0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
95 	0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c,
96 	0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
97 	0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4,
98 	0x22426260, 0x29092128, 0x07070304, 0x33033330,
99 	0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
100 	0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298,
101 };
102 
103 static const u32 SS1[256] = {
104 	0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2,
105 	0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
106 	0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
107 	0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
108 	0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1,
109 	0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
110 	0xd013c3d3, 0x90118191, 0x10110111, 0x04060602,
111 	0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
112 	0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
113 	0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
114 	0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2,
115 	0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
116 	0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32,
117 	0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
118 	0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
119 	0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
120 	0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0,
121 	0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
122 	0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13,
123 	0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
124 	0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
125 	0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
126 	0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1,
127 	0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
128 	0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131,
129 	0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
130 	0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
131 	0x20220222, 0x04040400, 0x68284860, 0x70314171,
132 	0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991,
133 	0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
134 	0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0,
135 	0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
136 	0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
137 	0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
138 	0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2,
139 	0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
140 	0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32,
141 	0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
142 	0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
143 	0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
144 	0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571,
145 	0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
146 	0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470,
147 	0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
148 	0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
149 	0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
150 	0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22,
151 	0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
152 	0x84058581, 0x14140410, 0x88098981, 0x981b8b93,
153 	0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
154 	0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
155 	0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
156 	0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11,
157 	0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
158 	0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3,
159 	0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
160 	0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
161 	0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
162 	0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622,
163 	0x30320232, 0x84048480, 0x68294961, 0x90138393,
164 	0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0,
165 	0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
166 	0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
167 	0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3,
168 };
169 
170 static const u32 SS2[256] = {
171 	0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3,
172 	0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
173 	0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
174 	0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
175 	0x20282808, 0x40440444, 0x20202000, 0x919c1d8d,
176 	0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
177 	0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b,
178 	0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
179 	0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
180 	0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
181 	0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747,
182 	0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
183 	0x20242404, 0x101c1c0c, 0x73703343, 0x90981888,
184 	0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
185 	0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
186 	0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
187 	0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb,
188 	0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
189 	0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848,
190 	0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
191 	0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
192 	0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
193 	0x131c1f0f, 0x91981989, 0x00000000, 0x11181909,
194 	0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
195 	0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707,
196 	0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
197 	0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
198 	0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
199 	0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5,
200 	0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
201 	0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a,
202 	0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
203 	0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
204 	0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
205 	0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5,
206 	0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
207 	0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e,
208 	0x32343606, 0x11141505, 0x22202202, 0x30383808,
209 	0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
210 	0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
211 	0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c,
212 	0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
213 	0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8,
214 	0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
215 	0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
216 	0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
217 	0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303,
218 	0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
219 	0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2,
220 	0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
221 	0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
222 	0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
223 	0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f,
224 	0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
225 	0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646,
226 	0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
227 	0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
228 	0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
229 	0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f,
230 	0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
231 	0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4,
232 	0x62602242, 0x21282909, 0x03040707, 0x33303303,
233 	0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
234 	0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a,
235 };
236 
237 static const u32 SS3[256] = {
238 	0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426,
239 	0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
240 	0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
241 	0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
242 	0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435,
243 	0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
244 	0xc3d3d013, 0x81919011, 0x01111011, 0x06020406,
245 	0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
246 	0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
247 	0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
248 	0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416,
249 	0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
250 	0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e,
251 	0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
252 	0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
253 	0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
254 	0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000,
255 	0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
256 	0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f,
257 	0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
258 	0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
259 	0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
260 	0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405,
261 	0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
262 	0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031,
263 	0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
264 	0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
265 	0x02222022, 0x04000404, 0x48606828, 0x41717031,
266 	0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819,
267 	0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
268 	0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c,
269 	0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
270 	0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
271 	0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
272 	0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022,
273 	0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
274 	0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a,
275 	0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
276 	0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
277 	0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
278 	0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435,
279 	0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
280 	0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434,
281 	0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
282 	0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
283 	0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
284 	0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a,
285 	0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
286 	0x85818405, 0x04101414, 0x89818809, 0x8b93981b,
287 	0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
288 	0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
289 	0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
290 	0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d,
291 	0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
292 	0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b,
293 	0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
294 	0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
295 	0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
296 	0x0e020c0e, 0x40505010, 0x09313839, 0x06222426,
297 	0x02323032, 0x84808404, 0x49616829, 0x83939013,
298 	0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424,
299 	0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
300 	0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
301 	0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437,
302 };
303 
304 static const u32 KC[SEED_NUM_KCONSTANTS] = {
305 	0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc,
306 	0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
307 	0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1,
308 	0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b,
309 };
310 
311 #define OP(X1, X2, X3, X4, rbase)			\
312 	t0 = X3 ^ ks[rbase];				\
313 	t1 = X4 ^ ks[rbase+1];				\
314 	t1 ^= t0;					\
315 	t1 = SS0[byte(t1, 0)] ^ SS1[byte(t1, 1)] ^	\
316 		SS2[byte(t1, 2)] ^ SS3[byte(t1, 3)];	\
317 	t0 += t1;					\
318 	t0 = SS0[byte(t0, 0)] ^ SS1[byte(t0, 1)] ^	\
319 		SS2[byte(t0, 2)] ^ SS3[byte(t0, 3)];	\
320 	t1 += t0;					\
321 	t1 = SS0[byte(t1, 0)] ^ SS1[byte(t1, 1)] ^	\
322 		SS2[byte(t1, 2)] ^ SS3[byte(t1, 3)];	\
323 	t0 += t1;					\
324 	X1 ^= t0;					\
325 	X2 ^= t1
326 
327 static int seed_set_key(struct crypto_tfm *tfm, const u8 *in_key,
328 		        unsigned int key_len)
329 {
330 	struct seed_ctx *ctx = crypto_tfm_ctx(tfm);
331 	u32 *keyout = ctx->keysched;
332 	const __be32 *key = (const __be32 *)in_key;
333 	u32 i, t0, t1, x1, x2, x3, x4;
334 
335 	x1 = be32_to_cpu(key[0]);
336 	x2 = be32_to_cpu(key[1]);
337 	x3 = be32_to_cpu(key[2]);
338 	x4 = be32_to_cpu(key[3]);
339 
340 	for (i = 0; i < SEED_NUM_KCONSTANTS; i++) {
341 		t0 = x1 + x3 - KC[i];
342 		t1 = x2 + KC[i] - x4;
343 		*(keyout++) = SS0[byte(t0, 0)] ^ SS1[byte(t0, 1)] ^
344 				SS2[byte(t0, 2)] ^ SS3[byte(t0, 3)];
345 		*(keyout++) = SS0[byte(t1, 0)] ^ SS1[byte(t1, 1)] ^
346 				SS2[byte(t1, 2)] ^ SS3[byte(t1, 3)];
347 
348 		if (i % 2 == 0) {
349 			t0 = x1;
350 			x1 = (x1 >> 8) ^ (x2 << 24);
351 			x2 = (x2 >> 8) ^ (t0 << 24);
352 		} else {
353 			t0 = x3;
354 			x3 = (x3 << 8) ^ (x4 >> 24);
355 			x4 = (x4 << 8) ^ (t0 >> 24);
356 		}
357 	}
358 
359 	return 0;
360 }
361 
362 /* encrypt a block of text */
363 
364 static void seed_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
365 {
366 	const struct seed_ctx *ctx = crypto_tfm_ctx(tfm);
367 	const __be32 *src = (const __be32 *)in;
368 	__be32 *dst = (__be32 *)out;
369 	u32 x1, x2, x3, x4, t0, t1;
370 	const u32 *ks = ctx->keysched;
371 
372 	x1 = be32_to_cpu(src[0]);
373 	x2 = be32_to_cpu(src[1]);
374 	x3 = be32_to_cpu(src[2]);
375 	x4 = be32_to_cpu(src[3]);
376 
377 	OP(x1, x2, x3, x4, 0);
378 	OP(x3, x4, x1, x2, 2);
379 	OP(x1, x2, x3, x4, 4);
380 	OP(x3, x4, x1, x2, 6);
381 	OP(x1, x2, x3, x4, 8);
382 	OP(x3, x4, x1, x2, 10);
383 	OP(x1, x2, x3, x4, 12);
384 	OP(x3, x4, x1, x2, 14);
385 	OP(x1, x2, x3, x4, 16);
386 	OP(x3, x4, x1, x2, 18);
387 	OP(x1, x2, x3, x4, 20);
388 	OP(x3, x4, x1, x2, 22);
389 	OP(x1, x2, x3, x4, 24);
390 	OP(x3, x4, x1, x2, 26);
391 	OP(x1, x2, x3, x4, 28);
392 	OP(x3, x4, x1, x2, 30);
393 
394 	dst[0] = cpu_to_be32(x3);
395 	dst[1] = cpu_to_be32(x4);
396 	dst[2] = cpu_to_be32(x1);
397 	dst[3] = cpu_to_be32(x2);
398 }
399 
400 /* decrypt a block of text */
401 
402 static void seed_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
403 {
404 	const struct seed_ctx *ctx = crypto_tfm_ctx(tfm);
405 	const __be32 *src = (const __be32 *)in;
406 	__be32 *dst = (__be32 *)out;
407 	u32 x1, x2, x3, x4, t0, t1;
408 	const u32 *ks = ctx->keysched;
409 
410 	x1 = be32_to_cpu(src[0]);
411 	x2 = be32_to_cpu(src[1]);
412 	x3 = be32_to_cpu(src[2]);
413 	x4 = be32_to_cpu(src[3]);
414 
415 	OP(x1, x2, x3, x4, 30);
416 	OP(x3, x4, x1, x2, 28);
417 	OP(x1, x2, x3, x4, 26);
418 	OP(x3, x4, x1, x2, 24);
419 	OP(x1, x2, x3, x4, 22);
420 	OP(x3, x4, x1, x2, 20);
421 	OP(x1, x2, x3, x4, 18);
422 	OP(x3, x4, x1, x2, 16);
423 	OP(x1, x2, x3, x4, 14);
424 	OP(x3, x4, x1, x2, 12);
425 	OP(x1, x2, x3, x4, 10);
426 	OP(x3, x4, x1, x2, 8);
427 	OP(x1, x2, x3, x4, 6);
428 	OP(x3, x4, x1, x2, 4);
429 	OP(x1, x2, x3, x4, 2);
430 	OP(x3, x4, x1, x2, 0);
431 
432 	dst[0] = cpu_to_be32(x3);
433 	dst[1] = cpu_to_be32(x4);
434 	dst[2] = cpu_to_be32(x1);
435 	dst[3] = cpu_to_be32(x2);
436 }
437 
438 
439 static struct crypto_alg seed_alg = {
440 	.cra_name		=	"seed",
441 	.cra_driver_name	=	"seed-generic",
442 	.cra_priority		=	100,
443 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
444 	.cra_blocksize		=	SEED_BLOCK_SIZE,
445 	.cra_ctxsize		=	sizeof(struct seed_ctx),
446 	.cra_alignmask		=	3,
447 	.cra_module		=	THIS_MODULE,
448 	.cra_u			=	{
449 		.cipher = {
450 			.cia_min_keysize	=	SEED_KEY_SIZE,
451 			.cia_max_keysize	=	SEED_KEY_SIZE,
452 			.cia_setkey		=	seed_set_key,
453 			.cia_encrypt		=	seed_encrypt,
454 			.cia_decrypt		=	seed_decrypt
455 		}
456 	}
457 };
458 
459 static int __init seed_init(void)
460 {
461 	return crypto_register_alg(&seed_alg);
462 }
463 
464 static void __exit seed_fini(void)
465 {
466 	crypto_unregister_alg(&seed_alg);
467 }
468 
469 subsys_initcall(seed_init);
470 module_exit(seed_fini);
471 
472 MODULE_DESCRIPTION("SEED Cipher Algorithm");
473 MODULE_LICENSE("GPL");
474 MODULE_AUTHOR("Hye-Shik Chang <perky@FreeBSD.org>, Kim Hyun <hkim@kisa.or.kr>");
475 MODULE_ALIAS_CRYPTO("seed");
476