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