crypto: tcrypt - do not attempt to write to readonly variable
[linux-2.6.git] / crypto / seed.c
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_list               =       LIST_HEAD_INIT(seed_alg.cra_list),
453         .cra_u                  =       {
454                 .cipher = {
455                         .cia_min_keysize        =       SEED_KEY_SIZE,
456                         .cia_max_keysize        =       SEED_KEY_SIZE,
457                         .cia_setkey             =       seed_set_key,
458                         .cia_encrypt            =       seed_encrypt,
459                         .cia_decrypt            =       seed_decrypt
460                 }
461         }
462 };
463
464 static int __init seed_init(void)
465 {
466         return crypto_register_alg(&seed_alg);
467 }
468
469 static void __exit seed_fini(void)
470 {
471         crypto_unregister_alg(&seed_alg);
472 }
473
474 module_init(seed_init);
475 module_exit(seed_fini);
476
477 MODULE_DESCRIPTION("SEED Cipher Algorithm");
478 MODULE_LICENSE("GPL");
479 MODULE_AUTHOR("Hye-Shik Chang <perky@FreeBSD.org>, Kim Hyun <hkim@kisa.or.kr>");