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