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