47ec9bc7c7c989c93d50bda2bfd67f257cb678a1
[openssl.git] / crypto / seed / seed.c
1 /*
2  * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Neither the name of author nor the names of its contributors may
10  *    be used to endorse or promote products derived from this software
11  *    without specific prior written permission.
12  *
13  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  */
26 #ifndef OPENSSL_NO_SEED
27
28 # include <stdio.h>
29 # include <stdlib.h>
30 # include <string.h>
31 # ifdef WIN32
32 #  include <memory.h>
33 # endif
34
35 # include <openssl/seed.h>
36 # include "seed_locl.h"
37
38 # ifdef SS                      /* can get defined on Solaris by inclusion of
39                                  * <stdlib.h> */
40 #  undef SS
41 # endif
42
43 # if !defined(OPENSSL_SMALL_FOOTPRINT)
44
45 #  define G_FUNC(v)       \
46         SS[0][(unsigned char)      (v) & 0xff] ^ \
47         SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \
48         SS[2][(unsigned char)((v)>>16) & 0xff] ^ \
49         SS[3][(unsigned char)((v)>>24) & 0xff]
50
51 static const seed_word SS[4][256] = {
52     { 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0,
53       0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
54       0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
55       0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
56       0x28082028, 0x04444044, 0x20002020, 0x1d8d919c,
57       0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
58       0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378,
59       0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
60       0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
61       0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
62       0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354,
63       0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
64       0x24042024, 0x1c0c101c, 0x33437370, 0x18889098,
65       0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
66       0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
67       0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
68       0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8,
69       0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
70       0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078,
71       0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
72       0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
73       0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
74       0x1f0f131c, 0x19899198, 0x00000000, 0x19091118,
75       0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
76       0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324,
77       0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
78       0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
79       0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
80       0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4,
81       0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
82       0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218,
83       0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
84       0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
85       0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
86       0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4,
87       0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
88       0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac,
89       0x36063234, 0x15051114, 0x22022220, 0x38083038,
90       0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
91       0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
92       0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c,
93       0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
94       0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8,
95       0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
96       0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
97       0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
98       0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320,
99       0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
100       0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0,
101       0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
102       0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
103       0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
104       0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c,
105       0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
106       0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244,
107       0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
108       0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
109       0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
110       0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c,
111       0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
112       0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4,
113       0x22426260, 0x29092128, 0x07070304, 0x33033330,
114       0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
115       0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298
116     },
117     { 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2,
118       0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
119       0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
120       0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
121       0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1,
122       0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
123       0xd013c3d3, 0x90118191, 0x10110111, 0x04060602,
124       0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
125       0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
126       0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
127       0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2,
128       0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
129       0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32,
130       0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
131       0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
132       0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
133       0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0,
134       0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
135       0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13,
136       0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
137       0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
138       0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
139       0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1,
140       0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
141       0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131,
142       0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
143       0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
144       0x20220222, 0x04040400, 0x68284860, 0x70314171,
145       0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991,
146       0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
147       0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0,
148       0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
149       0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
150       0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
151       0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2,
152       0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
153       0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32,
154       0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
155       0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
156       0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
157       0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571,
158       0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
159       0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470,
160       0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
161       0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
162       0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
163       0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22,
164       0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
165       0x84058581, 0x14140410, 0x88098981, 0x981b8b93,
166       0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
167       0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
168       0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
169       0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11,
170       0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
171       0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3,
172       0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
173       0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
174       0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
175       0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622,
176       0x30320232, 0x84048480, 0x68294961, 0x90138393,
177       0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0,
178       0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
179       0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
180       0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3
181     },
182     { 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3,
183       0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
184       0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
185       0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
186       0x20282808, 0x40440444, 0x20202000, 0x919c1d8d,
187       0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
188       0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b,
189       0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
190       0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
191       0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
192       0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747,
193       0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
194       0x20242404, 0x101c1c0c, 0x73703343, 0x90981888,
195       0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
196       0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
197       0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
198       0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb,
199       0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
200       0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848,
201       0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
202       0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
203       0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
204       0x131c1f0f, 0x91981989, 0x00000000, 0x11181909,
205       0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
206       0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707,
207       0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
208       0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
209       0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
210       0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5,
211       0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
212       0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a,
213       0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
214       0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
215       0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
216       0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5,
217       0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
218       0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e,
219       0x32343606, 0x11141505, 0x22202202, 0x30383808,
220       0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
221       0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
222       0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c,
223       0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
224       0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8,
225       0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
226       0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
227       0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
228       0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303,
229       0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
230       0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2,
231       0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
232       0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
233       0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
234       0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f,
235       0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
236       0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646,
237       0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
238       0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
239       0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
240       0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f,
241       0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
242       0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4,
243       0x62602242, 0x21282909, 0x03040707, 0x33303303,
244       0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
245       0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a
246     },
247     { 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426,
248       0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
249       0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
250       0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
251       0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435,
252       0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
253       0xc3d3d013, 0x81919011, 0x01111011, 0x06020406,
254       0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
255       0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
256       0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
257       0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416,
258       0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
259       0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e,
260       0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
261       0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
262       0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
263       0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000,
264       0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
265       0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f,
266       0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
267       0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
268       0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
269       0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405,
270       0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
271       0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031,
272       0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
273       0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
274       0x02222022, 0x04000404, 0x48606828, 0x41717031,
275       0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819,
276       0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
277       0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c,
278       0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
279       0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
280       0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
281       0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022,
282       0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
283       0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a,
284       0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
285       0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
286       0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
287       0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435,
288       0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
289       0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434,
290       0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
291       0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
292       0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
293       0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a,
294       0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
295       0x85818405, 0x04101414, 0x89818809, 0x8b93981b,
296       0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
297       0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
298       0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
299       0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d,
300       0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
301       0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b,
302       0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
303       0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
304       0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
305       0x0e020c0e, 0x40505010, 0x09313839, 0x06222426,
306       0x02323032, 0x84808404, 0x49616829, 0x83939013,
307       0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424,
308       0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
309       0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
310       0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437
311     }
312 };
313
314 #else
315
316 /* on x86_64 >5x size reduction at 40% performance penalty */
317 static const unsigned char SEED_Sbox[2][256] = {
318 {
319       0xA9, 0x85, 0xD6, 0xD3, 0x54, 0x1D, 0xAC, 0x25,
320       0x5D, 0x43, 0x18, 0x1E, 0x51, 0xFC, 0xCA, 0x63,
321       0x28, 0x44, 0x20, 0x9D, 0xE0, 0xE2, 0xC8, 0x17,
322       0xA5, 0x8F, 0x03, 0x7B, 0xBB, 0x13, 0xD2, 0xEE,
323       0x70, 0x8C, 0x3F, 0xA8, 0x32, 0xDD, 0xF6, 0x74,
324       0xEC, 0x95, 0x0B, 0x57, 0x5C, 0x5B, 0xBD, 0x01,
325       0x24, 0x1C, 0x73, 0x98, 0x10, 0xCC, 0xF2, 0xD9,
326       0x2C, 0xE7, 0x72, 0x83, 0x9B, 0xD1, 0x86, 0xC9,
327       0x60, 0x50, 0xA3, 0xEB, 0x0D, 0xB6, 0x9E, 0x4F,
328       0xB7, 0x5A, 0xC6, 0x78, 0xA6, 0x12, 0xAF, 0xD5,
329       0x61, 0xC3, 0xB4, 0x41, 0x52, 0x7D, 0x8D, 0x08,
330       0x1F, 0x99, 0x00, 0x19, 0x04, 0x53, 0xF7, 0xE1,
331       0xFD, 0x76, 0x2F, 0x27, 0xB0, 0x8B, 0x0E, 0xAB,
332       0xA2, 0x6E, 0x93, 0x4D, 0x69, 0x7C, 0x09, 0x0A,
333       0xBF, 0xEF, 0xF3, 0xC5, 0x87, 0x14, 0xFE, 0x64,
334       0xDE, 0x2E, 0x4B, 0x1A, 0x06, 0x21, 0x6B, 0x66,
335       0x02, 0xF5, 0x92, 0x8A, 0x0C, 0xB3, 0x7E, 0xD0,
336       0x7A, 0x47, 0x96, 0xE5, 0x26, 0x80, 0xAD, 0xDF,
337       0xA1, 0x30, 0x37, 0xAE, 0x36, 0x15, 0x22, 0x38,
338       0xF4, 0xA7, 0x45, 0x4C, 0x81, 0xE9, 0x84, 0x97,
339       0x35, 0xCB, 0xCE, 0x3C, 0x71, 0x11, 0xC7, 0x89,
340       0x75, 0xFB, 0xDA, 0xF8, 0x94, 0x59, 0x82, 0xC4,
341       0xFF, 0x49, 0x39, 0x67, 0xC0, 0xCF, 0xD7, 0xB8,
342       0x0F, 0x8E, 0x42, 0x23, 0x91, 0x6C, 0xDB, 0xA4,
343       0x34, 0xF1, 0x48, 0xC2, 0x6F, 0x3D, 0x2D, 0x40,
344       0xBE, 0x3E, 0xBC, 0xC1, 0xAA, 0xBA, 0x4E, 0x55,
345       0x3B, 0xDC, 0x68, 0x7F, 0x9C, 0xD8, 0x4A, 0x56,
346       0x77, 0xA0, 0xED, 0x46, 0xB5, 0x2B, 0x65, 0xFA,
347       0xE3, 0xB9, 0xB1, 0x9F, 0x5E, 0xF9, 0xE6, 0xB2,
348       0x31, 0xEA, 0x6D, 0x5F, 0xE4, 0xF0, 0xCD, 0x88,
349       0x16, 0x3A, 0x58, 0xD4, 0x62, 0x29, 0x07, 0x33,
350       0xE8, 0x1B, 0x05, 0x79, 0x90, 0x6A, 0x2A, 0x9A
351     },
352     {
353       0x38, 0xE8, 0x2D, 0xA6, 0xCF, 0xDE, 0xB3, 0xB8,
354       0xAF, 0x60, 0x55, 0xC7, 0x44, 0x6F, 0x6B, 0x5B,
355       0xC3, 0x62, 0x33, 0xB5, 0x29, 0xA0, 0xE2, 0xA7,
356       0xD3, 0x91, 0x11, 0x06, 0x1C, 0xBC, 0x36, 0x4B,
357       0xEF, 0x88, 0x6C, 0xA8, 0x17, 0xC4, 0x16, 0xF4,
358       0xC2, 0x45, 0xE1, 0xD6, 0x3F, 0x3D, 0x8E, 0x98,
359       0x28, 0x4E, 0xF6, 0x3E, 0xA5, 0xF9, 0x0D, 0xDF,
360       0xD8, 0x2B, 0x66, 0x7A, 0x27, 0x2F, 0xF1, 0x72,
361       0x42, 0xD4, 0x41, 0xC0, 0x73, 0x67, 0xAC, 0x8B,
362       0xF7, 0xAD, 0x80, 0x1F, 0xCA, 0x2C, 0xAA, 0x34,
363       0xD2, 0x0B, 0xEE, 0xE9, 0x5D, 0x94, 0x18, 0xF8,
364       0x57, 0xAE, 0x08, 0xC5, 0x13, 0xCD, 0x86, 0xB9,
365       0xFF, 0x7D, 0xC1, 0x31, 0xF5, 0x8A, 0x6A, 0xB1,
366       0xD1, 0x20, 0xD7, 0x02, 0x22, 0x04, 0x68, 0x71,
367       0x07, 0xDB, 0x9D, 0x99, 0x61, 0xBE, 0xE6, 0x59,
368       0xDD, 0x51, 0x90, 0xDC, 0x9A, 0xA3, 0xAB, 0xD0,
369       0x81, 0x0F, 0x47, 0x1A, 0xE3, 0xEC, 0x8D, 0xBF,
370       0x96, 0x7B, 0x5C, 0xA2, 0xA1, 0x63, 0x23, 0x4D,
371       0xC8, 0x9E, 0x9C, 0x3A, 0x0C, 0x2E, 0xBA, 0x6E,
372       0x9F, 0x5A, 0xF2, 0x92, 0xF3, 0x49, 0x78, 0xCC,
373       0x15, 0xFB, 0x70, 0x75, 0x7F, 0x35, 0x10, 0x03,
374       0x64, 0x6D, 0xC6, 0x74, 0xD5, 0xB4, 0xEA, 0x09,
375       0x76, 0x19, 0xFE, 0x40, 0x12, 0xE0, 0xBD, 0x05,
376       0xFA, 0x01, 0xF0, 0x2A, 0x5E, 0xA9, 0x56, 0x43,
377       0x85, 0x14, 0x89, 0x9B, 0xB0, 0xE5, 0x48, 0x79,
378       0x97, 0xFC, 0x1E, 0x82, 0x21, 0x8C, 0x1B, 0x5F,
379       0x77, 0x54, 0xB2, 0x1D, 0x25, 0x4F, 0x00, 0x46,
380       0xED, 0x58, 0x52, 0xEB, 0x7E, 0xDA, 0xC9, 0xFD,
381       0x30, 0x95, 0x65, 0x3C, 0xB6, 0xE4, 0xBB, 0x7C,
382       0x0E, 0x50, 0x39, 0x26, 0x32, 0x84, 0x69, 0x93,
383       0x37, 0xE7, 0x24, 0xA4, 0xCB, 0x53, 0x0A, 0x87,
384       0xD9, 0x4C, 0x83, 0x8F, 0xCE, 0x3B, 0x4A, 0xB7
385     }
386 };
387
388 static unsigned int G_FUNC(unsigned int v)
389 {
390     unsigned int s0, s1, s2, s3, ret;
391
392     s0 = SEED_Sbox[0][(unsigned char)      (v) & 0xff];
393     s1 = SEED_Sbox[1][(unsigned char)((v)>> 8) & 0xff];
394     s2 = SEED_Sbox[0][(unsigned char)((v)>>16) & 0xff];
395     s3 = SEED_Sbox[1][(unsigned char)((v)>>24) & 0xff];
396
397     ret  = ((s0 & 0xFC) ^ (s1 & 0xF3) ^ (s2 & 0xCF) ^ (s3 & 0x3F));
398     ret |= ((s0 & 0xF3) ^ (s1 & 0xCF) ^ (s2 & 0x3F) ^ (s3 & 0xFC)) << 8;
399     ret |= ((s0 & 0xCF) ^ (s1 & 0x3F) ^ (s2 & 0xFC) ^ (s3 & 0xF3)) << 16;
400     ret |= ((s0 & 0x3F) ^ (s1 & 0xFC) ^ (s2 & 0xF3) ^ (s3 & 0xCF)) << 24;
401
402     return ret;
403 }
404 # endif
405
406 /* key schedule constants - golden ratio */
407 # define KC0     0x9e3779b9
408 # define KC1     0x3c6ef373
409 # define KC2     0x78dde6e6
410 # define KC3     0xf1bbcdcc
411 # define KC4     0xe3779b99
412 # define KC5     0xc6ef3733
413 # define KC6     0x8dde6e67
414 # define KC7     0x1bbcdccf
415 # define KC8     0x3779b99e
416 # define KC9     0x6ef3733c
417 # define KC10    0xdde6e678
418 # define KC11    0xbbcdccf1
419 # define KC12    0x779b99e3
420 # define KC13    0xef3733c6
421 # define KC14    0xde6e678d
422 # define KC15    0xbcdccf1b
423
424 # if defined(OPENSSL_SMALL_FOOTPRINT)
425 static const seed_word KC[] = {
426     KC0, KC1, KC2, KC3, KC4, KC5, KC6, KC7,
427     KC8, KC9, KC10, KC11, KC12, KC13, KC14, KC15
428 };
429 # endif
430
431 void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
432                   SEED_KEY_SCHEDULE *ks)
433 {
434     seed_word x1, x2, x3, x4;
435     seed_word t0, t1;
436
437     char2word(rawkey, x1);
438     char2word(rawkey + 4, x2);
439     char2word(rawkey + 8, x3);
440     char2word(rawkey + 12, x4);
441
442     t0 = (x1 + x3 - KC0) & 0xffffffff;
443     t1 = (x2 - x4 + KC0) & 0xffffffff;
444     KEYUPDATE_TEMP(t0, t1, &ks->data[0]);
445     KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1);
446     KEYUPDATE_TEMP(t0, t1, &ks->data[2]);
447
448 # if !defined(OPENSSL_SMALL_FOOTPRINT)
449     KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2);
450     KEYUPDATE_TEMP(t0, t1, &ks->data[4]);
451     KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3);
452     KEYUPDATE_TEMP(t0, t1, &ks->data[6]);
453     KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4);
454     KEYUPDATE_TEMP(t0, t1, &ks->data[8]);
455     KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5);
456     KEYUPDATE_TEMP(t0, t1, &ks->data[10]);
457     KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6);
458     KEYUPDATE_TEMP(t0, t1, &ks->data[12]);
459     KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7);
460     KEYUPDATE_TEMP(t0, t1, &ks->data[14]);
461     KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8);
462     KEYUPDATE_TEMP(t0, t1, &ks->data[16]);
463     KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9);
464     KEYUPDATE_TEMP(t0, t1, &ks->data[18]);
465     KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10);
466     KEYUPDATE_TEMP(t0, t1, &ks->data[20]);
467     KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11);
468     KEYUPDATE_TEMP(t0, t1, &ks->data[22]);
469     KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12);
470     KEYUPDATE_TEMP(t0, t1, &ks->data[24]);
471     KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13);
472     KEYUPDATE_TEMP(t0, t1, &ks->data[26]);
473     KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14);
474     KEYUPDATE_TEMP(t0, t1, &ks->data[28]);
475     KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15);
476     KEYUPDATE_TEMP(t0, t1, &ks->data[30]);
477 # else
478     {
479         int i;
480         for (i = 2; i < 16; i += 2) {
481             KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC[i]);
482             KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2]);
483             KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC[i + 1]);
484             KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2 + 2]);
485         }
486     }
487 # endif
488 }
489
490 void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE],
491                   unsigned char d[SEED_BLOCK_SIZE],
492                   const SEED_KEY_SCHEDULE *ks)
493 {
494     seed_word x1, x2, x3, x4;
495     seed_word t0, t1;
496
497     char2word(s, x1);
498     char2word(s + 4, x2);
499     char2word(s + 8, x3);
500     char2word(s + 12, x4);
501
502 # if !defined(OPENSSL_SMALL_FOOTPRINT)
503     E_SEED(t0, t1, x1, x2, x3, x4, 0);
504     E_SEED(t0, t1, x3, x4, x1, x2, 2);
505     E_SEED(t0, t1, x1, x2, x3, x4, 4);
506     E_SEED(t0, t1, x3, x4, x1, x2, 6);
507     E_SEED(t0, t1, x1, x2, x3, x4, 8);
508     E_SEED(t0, t1, x3, x4, x1, x2, 10);
509     E_SEED(t0, t1, x1, x2, x3, x4, 12);
510     E_SEED(t0, t1, x3, x4, x1, x2, 14);
511     E_SEED(t0, t1, x1, x2, x3, x4, 16);
512     E_SEED(t0, t1, x3, x4, x1, x2, 18);
513     E_SEED(t0, t1, x1, x2, x3, x4, 20);
514     E_SEED(t0, t1, x3, x4, x1, x2, 22);
515     E_SEED(t0, t1, x1, x2, x3, x4, 24);
516     E_SEED(t0, t1, x3, x4, x1, x2, 26);
517     E_SEED(t0, t1, x1, x2, x3, x4, 28);
518     E_SEED(t0, t1, x3, x4, x1, x2, 30);
519 # else
520     {
521         int i;
522         for (i = 0; i < 30; i += 4) {
523             E_SEED(t0, t1, x1, x2, x3, x4, i);
524             E_SEED(t0, t1, x3, x4, x1, x2, i + 2);
525         }
526     }
527 # endif
528
529     word2char(x3, d);
530     word2char(x4, d + 4);
531     word2char(x1, d + 8);
532     word2char(x2, d + 12);
533 }
534
535 void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
536                   unsigned char d[SEED_BLOCK_SIZE],
537                   const SEED_KEY_SCHEDULE *ks)
538 {
539     seed_word x1, x2, x3, x4;
540     seed_word t0, t1;
541
542     char2word(s, x1);
543     char2word(s + 4, x2);
544     char2word(s + 8, x3);
545     char2word(s + 12, x4);
546
547 # if !defined(OPENSSL_SMALL_FOOTPRINT)
548     E_SEED(t0, t1, x1, x2, x3, x4, 30);
549     E_SEED(t0, t1, x3, x4, x1, x2, 28);
550     E_SEED(t0, t1, x1, x2, x3, x4, 26);
551     E_SEED(t0, t1, x3, x4, x1, x2, 24);
552     E_SEED(t0, t1, x1, x2, x3, x4, 22);
553     E_SEED(t0, t1, x3, x4, x1, x2, 20);
554     E_SEED(t0, t1, x1, x2, x3, x4, 18);
555     E_SEED(t0, t1, x3, x4, x1, x2, 16);
556     E_SEED(t0, t1, x1, x2, x3, x4, 14);
557     E_SEED(t0, t1, x3, x4, x1, x2, 12);
558     E_SEED(t0, t1, x1, x2, x3, x4, 10);
559     E_SEED(t0, t1, x3, x4, x1, x2, 8);
560     E_SEED(t0, t1, x1, x2, x3, x4, 6);
561     E_SEED(t0, t1, x3, x4, x1, x2, 4);
562     E_SEED(t0, t1, x1, x2, x3, x4, 2);
563     E_SEED(t0, t1, x3, x4, x1, x2, 0);
564 # else
565     {
566         int i;
567         for (i = 30; i > 0; i -= 4) {
568             E_SEED(t0, t1, x1, x2, x3, x4, i);
569             E_SEED(t0, t1, x3, x4, x1, x2, i - 2);
570
571         }
572     }
573 # endif
574
575     word2char(x3, d);
576     word2char(x4, d + 4);
577     word2char(x1, d + 8);
578     word2char(x2, d + 12);
579 }
580
581 #endif                          /* OPENSSL_NO_SEED */