mpi/ec: fix when 'unsigned long' is 32-bit but limb size is 64-bit
[libgcrypt.git] / cipher / cast5.c
1 /* cast5.c  -  CAST5 cipher (RFC2144)
2  *      Copyright (C) 1998, 2001, 2002, 2003 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 /* Test vectors:
22  *
23  * 128-bit key         = 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A
24  *         plaintext   = 01 23 45 67 89 AB CD EF
25  *         ciphertext  = 23 8B 4F E5 84 7E 44 B2
26  *
27  * 80-bit  key         = 01 23 45 67 12 34 56 78 23 45
28  *                     = 01 23 45 67 12 34 56 78 23 45 00 00 00 00 00 00
29  *         plaintext   = 01 23 45 67 89 AB CD EF
30  *         ciphertext  = EB 6A 71 1A 2C 02 27 1B
31  *
32  * 40-bit  key         = 01 23 45 67 12
33  *                     = 01 23 45 67 12 00 00 00 00 00 00 00 00 00 00 00
34  *         plaintext   = 01 23 45 67 89 AB CD EF
35  *         ciphertext  = 7A C8 16 D1 6E 9B 30 2E
36  */
37
38 #include <config.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include "g10lib.h"
43 #include "types.h"
44 #include "cipher.h"
45 #include "bithelp.h"
46 #include "bufhelp.h"
47 #include "cipher-selftest.h"
48
49 /* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */
50 #undef USE_AMD64_ASM
51 #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
52     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
53 # define USE_AMD64_ASM 1
54 #endif
55
56 /* USE_ARM_ASM indicates whether to use ARM assembly code. */
57 #undef USE_ARM_ASM
58 #if defined(__ARMEL__)
59 # ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
60 #  define USE_ARM_ASM 1
61 # endif
62 #endif
63
64 #define CAST5_BLOCKSIZE 8
65
66 typedef struct {
67     u32  Km[16];
68     byte Kr[16];
69 #ifdef USE_ARM_ASM
70     u32 Kr_arm_enc[16 / sizeof(u32)];
71     u32 Kr_arm_dec[16 / sizeof(u32)];
72 #endif
73 } CAST5_context;
74
75 static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen);
76 static unsigned int encrypt_block (void *c, byte *outbuf, const byte *inbuf);
77 static unsigned int decrypt_block (void *c, byte *outbuf, const byte *inbuf);
78
79
80
81 #define s1 _gcry_cast5_s1to4[0]
82 #define s2 _gcry_cast5_s1to4[1]
83 #define s3 _gcry_cast5_s1to4[2]
84 #define s4 _gcry_cast5_s1to4[3]
85
86 const u32 _gcry_cast5_s1to4[4][256] = { {
87 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
88 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
89 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
90 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
91 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
92 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
93 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
94 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
95 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
96 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
97 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
98 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
99 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
100 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
101 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
102 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
103 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
104 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
105 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
106 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
107 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
108 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
109 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
110 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
111 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
112 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
113 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
114 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
115 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
116 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
117 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
118 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
119 }, {
120 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
121 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
122 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
123 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
124 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
125 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
126 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
127 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
128 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
129 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
130 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
131 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
132 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
133 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
134 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
135 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
136 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
137 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
138 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
139 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
140 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
141 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
142 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
143 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
144 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
145 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
146 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
147 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
148 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
149 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
150 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
151 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
152 }, {
153 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
154 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
155 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
156 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
157 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
158 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
159 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
160 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
161 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
162 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
163 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
164 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
165 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
166 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
167 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
168 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
169 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
170 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
171 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
172 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
173 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
174 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
175 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
176 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
177 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
178 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
179 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
180 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
181 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
182 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
183 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
184 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
185 }, {
186 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
187 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
188 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
189 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
190 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
191 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
192 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
193 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
194 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
195 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
196 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
197 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
198 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
199 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
200 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
201 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
202 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
203 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
204 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
205 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
206 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
207 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
208 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
209 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
210 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
211 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
212 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
213 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
214 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
215 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
216 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
217 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
218 } };
219 static const u32 s5[256] = {
220 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
221 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
222 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
223 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
224 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
225 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
226 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
227 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
228 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
229 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
230 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
231 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
232 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
233 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
234 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
235 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
236 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
237 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
238 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
239 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
240 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
241 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
242 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
243 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
244 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
245 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
246 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
247 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
248 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
249 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
250 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
251 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
252 };
253 static const u32 s6[256] = {
254 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
255 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
256 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
257 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
258 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
259 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
260 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
261 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
262 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
263 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
264 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
265 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
266 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
267 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
268 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
269 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
270 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
271 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
272 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
273 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
274 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
275 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
276 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
277 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
278 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
279 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
280 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
281 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
282 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
283 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
284 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
285 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
286 };
287 static const u32 s7[256] = {
288 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
289 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
290 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
291 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
292 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
293 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
294 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
295 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
296 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
297 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
298 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
299 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
300 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
301 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
302 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
303 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
304 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
305 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
306 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
307 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
308 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
309 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
310 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
311 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
312 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
313 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
314 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
315 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
316 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
317 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
318 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
319 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
320 };
321 static const u32 s8[256] = {
322 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
323 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
324 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
325 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
326 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
327 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
328 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
329 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
330 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
331 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
332 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
333 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
334 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
335 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
336 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
337 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
338 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
339 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
340 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
341 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
342 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
343 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
344 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
345 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
346 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
347 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
348 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
349 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
350 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
351 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
352 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
353 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
354 };
355
356
357 #ifdef USE_AMD64_ASM
358
359 /* Assembly implementations of CAST5. */
360 extern void _gcry_cast5_amd64_encrypt_block(CAST5_context *c, byte *outbuf,
361                                             const byte *inbuf);
362
363 extern void _gcry_cast5_amd64_decrypt_block(CAST5_context *c, byte *outbuf,
364                                             const byte *inbuf);
365
366 /* These assembly implementations process four blocks in parallel. */
367 extern void _gcry_cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out,
368                                       const byte *in, byte *ctr);
369
370 extern void _gcry_cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out,
371                                       const byte *in, byte *iv);
372
373 extern void _gcry_cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out,
374                                       const byte *in, byte *iv);
375
376 #ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
377 static inline void
378 call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
379               const void *arg3, const void *arg4)
380 {
381   /* Call SystemV ABI function without storing non-volatile XMM registers,
382    * as target function does not use vector instruction sets. */
383   asm volatile ("callq *%0\n\t"
384                 : "+a" (fn),
385                   "+D" (arg1),
386                   "+S" (arg2),
387                   "+d" (arg3),
388                   "+c" (arg4)
389                 :
390                 : "cc", "memory", "r8", "r9", "r10", "r11");
391 }
392 #endif
393
394 static void
395 do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
396 {
397 #ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
398   call_sysv_fn (_gcry_cast5_amd64_encrypt_block, context, outbuf, inbuf, NULL);
399 #else
400   _gcry_cast5_amd64_encrypt_block (context, outbuf, inbuf);
401 #endif
402 }
403
404 static void
405 do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
406 {
407 #ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
408   call_sysv_fn (_gcry_cast5_amd64_decrypt_block, context, outbuf, inbuf, NULL);
409 #else
410   _gcry_cast5_amd64_decrypt_block (context, outbuf, inbuf);
411 #endif
412 }
413
414 static void
415 cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out, const byte *in, byte *ctr)
416 {
417 #ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
418   call_sysv_fn (_gcry_cast5_amd64_ctr_enc, ctx, out, in, ctr);
419 #else
420   _gcry_cast5_amd64_ctr_enc (ctx, out, in, ctr);
421 #endif
422 }
423
424 static void
425 cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv)
426 {
427 #ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
428   call_sysv_fn (_gcry_cast5_amd64_cbc_dec, ctx, out, in, iv);
429 #else
430   _gcry_cast5_amd64_cbc_dec (ctx, out, in, iv);
431 #endif
432 }
433
434 static void
435 cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv)
436 {
437 #ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
438   call_sysv_fn (_gcry_cast5_amd64_cfb_dec, ctx, out, in, iv);
439 #else
440   _gcry_cast5_amd64_cfb_dec (ctx, out, in, iv);
441 #endif
442 }
443
444 static unsigned int
445 encrypt_block (void *context , byte *outbuf, const byte *inbuf)
446 {
447   CAST5_context *c = (CAST5_context *) context;
448   do_encrypt_block (c, outbuf, inbuf);
449   return /*burn_stack*/ (2*8);
450 }
451
452 static unsigned int
453 decrypt_block (void *context, byte *outbuf, const byte *inbuf)
454 {
455   CAST5_context *c = (CAST5_context *) context;
456   do_decrypt_block (c, outbuf, inbuf);
457   return /*burn_stack*/ (2*8);
458 }
459
460 #elif defined(USE_ARM_ASM)
461
462 /* ARM assembly implementations of CAST5. */
463 extern void _gcry_cast5_arm_encrypt_block(CAST5_context *c, byte *outbuf,
464                                             const byte *inbuf);
465
466 extern void _gcry_cast5_arm_decrypt_block(CAST5_context *c, byte *outbuf,
467                                             const byte *inbuf);
468
469 /* These assembly implementations process two blocks in parallel. */
470 extern void _gcry_cast5_arm_ctr_enc(CAST5_context *ctx, byte *out,
471                                       const byte *in, byte *ctr);
472
473 extern void _gcry_cast5_arm_cbc_dec(CAST5_context *ctx, byte *out,
474                                       const byte *in, byte *iv);
475
476 extern void _gcry_cast5_arm_cfb_dec(CAST5_context *ctx, byte *out,
477                                       const byte *in, byte *iv);
478
479 static void
480 do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
481 {
482   _gcry_cast5_arm_encrypt_block (context, outbuf, inbuf);
483 }
484
485 static void
486 do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
487 {
488   _gcry_cast5_arm_decrypt_block (context, outbuf, inbuf);
489 }
490
491 static unsigned int
492 encrypt_block (void *context , byte *outbuf, const byte *inbuf)
493 {
494   CAST5_context *c = (CAST5_context *) context;
495   do_encrypt_block (c, outbuf, inbuf);
496   return /*burn_stack*/ (10*4);
497 }
498
499 static unsigned int
500 decrypt_block (void *context, byte *outbuf, const byte *inbuf)
501 {
502   CAST5_context *c = (CAST5_context *) context;
503   do_decrypt_block (c, outbuf, inbuf);
504   return /*burn_stack*/ (10*4);
505 }
506
507 #else /*USE_ARM_ASM*/
508
509 #define F1(D,m,r)  (  (I = ((m) + (D))), (I=rol(I,(r))),   \
510     (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
511 #define F2(D,m,r)  (  (I = ((m) ^ (D))), (I=rol(I,(r))),   \
512     (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
513 #define F3(D,m,r)  (  (I = ((m) - (D))), (I=rol(I,(r))),   \
514     (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
515
516 static void
517 do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
518 {
519     u32 l, r, t;
520     u32 I;   /* used by the Fx macros */
521     u32 *Km;
522     byte *Kr;
523
524     Km = c->Km;
525     Kr = c->Kr;
526
527     /* (L0,R0) <-- (m1...m64).  (Split the plaintext into left and
528      * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
529      */
530     l = buf_get_be32(inbuf + 0);
531     r = buf_get_be32(inbuf + 4);
532
533     /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
534      *  Li = Ri-1;
535      *  Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
536      * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
537      * Rounds 2, 5, 8, 11, and 14 use f function Type 2.
538      * Rounds 3, 6, 9, 12, and 15 use f function Type 3.
539      */
540
541     t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
542     t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
543     t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
544     t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
545     t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
546     t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
547     t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
548     t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
549     t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
550     t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
551     t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
552     t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
553     t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
554     t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
555     t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
556     t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
557
558     /* c1...c64 <-- (R16,L16).  (Exchange final blocks L16, R16 and
559      *  concatenate to form the ciphertext.) */
560     buf_put_be32(outbuf + 0, r);
561     buf_put_be32(outbuf + 4, l);
562 }
563
564 static unsigned int
565 encrypt_block (void *context , byte *outbuf, const byte *inbuf)
566 {
567   CAST5_context *c = (CAST5_context *) context;
568   do_encrypt_block (c, outbuf, inbuf);
569   return /*burn_stack*/ (20+4*sizeof(void*));
570 }
571
572
573 static void
574 do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
575 {
576     u32 l, r, t;
577     u32 I;
578     u32 *Km;
579     byte *Kr;
580
581     Km = c->Km;
582     Kr = c->Kr;
583
584     l = buf_get_be32(inbuf + 0);
585     r = buf_get_be32(inbuf + 4);
586
587     t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
588     t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
589     t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
590     t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
591     t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
592     t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
593     t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
594     t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
595     t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
596     t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
597     t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
598     t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
599     t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
600     t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
601     t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
602     t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
603
604     buf_put_be32(outbuf + 0, r);
605     buf_put_be32(outbuf + 4, l);
606 }
607
608 static unsigned int
609 decrypt_block (void *context, byte *outbuf, const byte *inbuf)
610 {
611   CAST5_context *c = (CAST5_context *) context;
612   do_decrypt_block (c, outbuf, inbuf);
613   return /*burn_stack*/ (20+4*sizeof(void*));
614 }
615
616 #endif /*!USE_ARM_ASM*/
617
618
619 /* Bulk encryption of complete blocks in CTR mode.  This function is only
620    intended for the bulk encryption feature of cipher.c.  CTR is expected to be
621    of size CAST5_BLOCKSIZE. */
622 void
623 _gcry_cast5_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
624                     const void *inbuf_arg, size_t nblocks)
625 {
626   CAST5_context *ctx = context;
627   unsigned char *outbuf = outbuf_arg;
628   const unsigned char *inbuf = inbuf_arg;
629   unsigned char tmpbuf[CAST5_BLOCKSIZE];
630   int burn_stack_depth = (20 + 4 * sizeof(void*)) + 2 * CAST5_BLOCKSIZE;
631
632   int i;
633
634 #ifdef USE_AMD64_ASM
635   {
636     if (nblocks >= 4)
637       burn_stack_depth += 8 * sizeof(void*);
638
639     /* Process data in 4 block chunks. */
640     while (nblocks >= 4)
641       {
642         cast5_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
643
644         nblocks -= 4;
645         outbuf += 4 * CAST5_BLOCKSIZE;
646         inbuf  += 4 * CAST5_BLOCKSIZE;
647       }
648
649     /* Use generic code to handle smaller chunks... */
650     /* TODO: use caching instead? */
651   }
652 #elif defined(USE_ARM_ASM)
653   {
654     /* Process data in 2 block chunks. */
655     while (nblocks >= 2)
656       {
657         _gcry_cast5_arm_ctr_enc(ctx, outbuf, inbuf, ctr);
658
659         nblocks -= 2;
660         outbuf += 2 * CAST5_BLOCKSIZE;
661         inbuf  += 2 * CAST5_BLOCKSIZE;
662       }
663
664     /* Use generic code to handle smaller chunks... */
665     /* TODO: use caching instead? */
666   }
667 #endif
668
669   for ( ;nblocks; nblocks-- )
670     {
671       /* Encrypt the counter. */
672       do_encrypt_block(ctx, tmpbuf, ctr);
673       /* XOR the input with the encrypted counter and store in output.  */
674       buf_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE);
675       outbuf += CAST5_BLOCKSIZE;
676       inbuf  += CAST5_BLOCKSIZE;
677       /* Increment the counter.  */
678       for (i = CAST5_BLOCKSIZE; i > 0; i--)
679         {
680           ctr[i-1]++;
681           if (ctr[i-1])
682             break;
683         }
684     }
685
686   wipememory(tmpbuf, sizeof(tmpbuf));
687   _gcry_burn_stack(burn_stack_depth);
688 }
689
690
691 /* Bulk decryption of complete blocks in CBC mode.  This function is only
692    intended for the bulk encryption feature of cipher.c. */
693 void
694 _gcry_cast5_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
695                     const void *inbuf_arg, size_t nblocks)
696 {
697   CAST5_context *ctx = context;
698   unsigned char *outbuf = outbuf_arg;
699   const unsigned char *inbuf = inbuf_arg;
700   unsigned char savebuf[CAST5_BLOCKSIZE];
701   int burn_stack_depth = (20 + 4 * sizeof(void*)) + 2 * CAST5_BLOCKSIZE;
702
703 #ifdef USE_AMD64_ASM
704   {
705     if (nblocks >= 4)
706       burn_stack_depth += 8 * sizeof(void*);
707
708     /* Process data in 4 block chunks. */
709     while (nblocks >= 4)
710       {
711         cast5_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
712
713         nblocks -= 4;
714         outbuf += 4 * CAST5_BLOCKSIZE;
715         inbuf  += 4 * CAST5_BLOCKSIZE;
716       }
717
718     /* Use generic code to handle smaller chunks... */
719   }
720 #elif defined(USE_ARM_ASM)
721   {
722     /* Process data in 2 block chunks. */
723     while (nblocks >= 2)
724       {
725         _gcry_cast5_arm_cbc_dec(ctx, outbuf, inbuf, iv);
726
727         nblocks -= 2;
728         outbuf += 2 * CAST5_BLOCKSIZE;
729         inbuf  += 2 * CAST5_BLOCKSIZE;
730       }
731
732     /* Use generic code to handle smaller chunks... */
733   }
734 #endif
735
736   for ( ;nblocks; nblocks-- )
737     {
738       /* INBUF is needed later and it may be identical to OUTBUF, so store
739          the intermediate result to SAVEBUF.  */
740       do_decrypt_block (ctx, savebuf, inbuf);
741
742       buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAST5_BLOCKSIZE);
743       inbuf += CAST5_BLOCKSIZE;
744       outbuf += CAST5_BLOCKSIZE;
745     }
746
747   wipememory(savebuf, sizeof(savebuf));
748   _gcry_burn_stack(burn_stack_depth);
749 }
750
751 /* Bulk decryption of complete blocks in CFB mode.  This function is only
752    intended for the bulk encryption feature of cipher.c. */
753 void
754 _gcry_cast5_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
755                     const void *inbuf_arg, size_t nblocks)
756 {
757   CAST5_context *ctx = context;
758   unsigned char *outbuf = outbuf_arg;
759   const unsigned char *inbuf = inbuf_arg;
760   int burn_stack_depth = (20 + 4 * sizeof(void*)) + 2 * CAST5_BLOCKSIZE;
761
762 #ifdef USE_AMD64_ASM
763   {
764     if (nblocks >= 4)
765       burn_stack_depth += 8 * sizeof(void*);
766
767     /* Process data in 4 block chunks. */
768     while (nblocks >= 4)
769       {
770         cast5_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
771
772         nblocks -= 4;
773         outbuf += 4 * CAST5_BLOCKSIZE;
774         inbuf  += 4 * CAST5_BLOCKSIZE;
775       }
776
777     /* Use generic code to handle smaller chunks... */
778   }
779 #elif defined(USE_ARM_ASM)
780   {
781     /* Process data in 2 block chunks. */
782     while (nblocks >= 2)
783       {
784         _gcry_cast5_arm_cfb_dec(ctx, outbuf, inbuf, iv);
785
786         nblocks -= 2;
787         outbuf += 2 * CAST5_BLOCKSIZE;
788         inbuf  += 2 * CAST5_BLOCKSIZE;
789       }
790
791     /* Use generic code to handle smaller chunks... */
792   }
793 #endif
794
795   for ( ;nblocks; nblocks-- )
796     {
797       do_encrypt_block(ctx, iv, iv);
798       buf_xor_n_copy(outbuf, iv, inbuf, CAST5_BLOCKSIZE);
799       outbuf += CAST5_BLOCKSIZE;
800       inbuf  += CAST5_BLOCKSIZE;
801     }
802
803   _gcry_burn_stack(burn_stack_depth);
804 }
805
806
807 /* Run the self-tests for CAST5-CTR, tests IV increment of bulk CTR
808    encryption.  Returns NULL on success. */
809 static const char *
810 selftest_ctr (void)
811 {
812   const int nblocks = 4+1;
813   const int blocksize = CAST5_BLOCKSIZE;
814   const int context_size = sizeof(CAST5_context);
815
816   return _gcry_selftest_helper_ctr("CAST5", &cast_setkey,
817            &encrypt_block, &_gcry_cast5_ctr_enc, nblocks, blocksize,
818            context_size);
819 }
820
821
822 /* Run the self-tests for CAST5-CBC, tests bulk CBC decryption.
823    Returns NULL on success. */
824 static const char *
825 selftest_cbc (void)
826 {
827   const int nblocks = 4+2;
828   const int blocksize = CAST5_BLOCKSIZE;
829   const int context_size = sizeof(CAST5_context);
830
831   return _gcry_selftest_helper_cbc("CAST5", &cast_setkey,
832            &encrypt_block, &_gcry_cast5_cbc_dec, nblocks, blocksize,
833            context_size);
834 }
835
836
837 /* Run the self-tests for CAST5-CFB, tests bulk CBC decryption.
838    Returns NULL on success. */
839 static const char *
840 selftest_cfb (void)
841 {
842   const int nblocks = 4+2;
843   const int blocksize = CAST5_BLOCKSIZE;
844   const int context_size = sizeof(CAST5_context);
845
846   return _gcry_selftest_helper_cfb("CAST5", &cast_setkey,
847            &encrypt_block, &_gcry_cast5_cfb_dec, nblocks, blocksize,
848            context_size);
849 }
850
851
852 static const char*
853 selftest(void)
854 {
855     CAST5_context c;
856     static const byte key[16] =
857                     { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
858                       0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A  };
859     static const byte plain[8] =
860                     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
861     static const byte cipher[8] =
862                     { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
863     byte buffer[8];
864     const char *r;
865
866     cast_setkey( &c, key, 16 );
867     encrypt_block( &c, buffer, plain );
868     if( memcmp( buffer, cipher, 8 ) )
869         return "1";
870     decrypt_block( &c, buffer, buffer );
871     if( memcmp( buffer, plain, 8 ) )
872         return "2";
873
874 #if 0 /* full maintenance test */
875     {
876         int i;
877         byte a0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
878                         0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
879         byte b0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
880                         0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
881         byte a1[16] = { 0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
882                         0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92 };
883         byte b1[16] = { 0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
884                         0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E };
885
886         for(i=0; i < 1000000; i++ ) {
887             cast_setkey( &c, b0, 16 );
888             encrypt_block( &c, a0, a0 );
889             encrypt_block( &c, a0+8, a0+8 );
890             cast_setkey( &c, a0, 16 );
891             encrypt_block( &c, b0, b0 );
892             encrypt_block( &c, b0+8, b0+8 );
893         }
894         if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) )
895             return "3";
896
897     }
898 #endif
899
900     if ( (r = selftest_cbc ()) )
901       return r;
902
903     if ( (r = selftest_cfb ()) )
904       return r;
905
906     if ( (r = selftest_ctr ()) )
907       return r;
908
909     return NULL;
910 }
911
912
913 static void
914 key_schedule( u32 *x, u32 *z, u32 *k )
915 {
916
917 #define xi(i)   ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
918 #define zi(i)   ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
919
920     z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
921     z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
922     z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
923     z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
924     k[0] = s5[zi( 8)]^s6[zi( 9)]^s7[zi( 7)]^s8[zi( 6)]^s5[zi( 2)];
925     k[1] = s5[zi(10)]^s6[zi(11)]^s7[zi( 5)]^s8[zi( 4)]^s6[zi( 6)];
926     k[2] = s5[zi(12)]^s6[zi(13)]^s7[zi( 3)]^s8[zi( 2)]^s7[zi( 9)];
927     k[3] = s5[zi(14)]^s6[zi(15)]^s7[zi( 1)]^s8[zi( 0)]^s8[zi(12)];
928
929     x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
930     x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
931     x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
932     x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
933     k[4] = s5[xi( 3)]^s6[xi( 2)]^s7[xi(12)]^s8[xi(13)]^s5[xi( 8)];
934     k[5] = s5[xi( 1)]^s6[xi( 0)]^s7[xi(14)]^s8[xi(15)]^s6[xi(13)];
935     k[6] = s5[xi( 7)]^s6[xi( 6)]^s7[xi( 8)]^s8[xi( 9)]^s7[xi( 3)];
936     k[7] = s5[xi( 5)]^s6[xi( 4)]^s7[xi(10)]^s8[xi(11)]^s8[xi( 7)];
937
938     z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
939     z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
940     z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
941     z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
942     k[8] = s5[zi( 3)]^s6[zi( 2)]^s7[zi(12)]^s8[zi(13)]^s5[zi( 9)];
943     k[9] = s5[zi( 1)]^s6[zi( 0)]^s7[zi(14)]^s8[zi(15)]^s6[zi(12)];
944     k[10]= s5[zi( 7)]^s6[zi( 6)]^s7[zi( 8)]^s8[zi( 9)]^s7[zi( 2)];
945     k[11]= s5[zi( 5)]^s6[zi( 4)]^s7[zi(10)]^s8[zi(11)]^s8[zi( 6)];
946
947     x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
948     x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
949     x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
950     x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
951     k[12]= s5[xi( 8)]^s6[xi( 9)]^s7[xi( 7)]^s8[xi( 6)]^s5[xi( 3)];
952     k[13]= s5[xi(10)]^s6[xi(11)]^s7[xi( 5)]^s8[xi( 4)]^s6[xi( 7)];
953     k[14]= s5[xi(12)]^s6[xi(13)]^s7[xi( 3)]^s8[xi( 2)]^s7[xi( 8)];
954     k[15]= s5[xi(14)]^s6[xi(15)]^s7[xi( 1)]^s8[xi( 0)]^s8[xi(13)];
955
956 #undef xi
957 #undef zi
958 }
959
960
961 static gcry_err_code_t
962 do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
963 {
964   static int initialized;
965   static const char* selftest_failed;
966   int i;
967   u32 x[4];
968   u32 z[4];
969   u32 k[16];
970
971   if( !initialized )
972     {
973       initialized = 1;
974       selftest_failed = selftest();
975       if( selftest_failed )
976         log_error ("CAST5 selftest failed (%s).\n", selftest_failed );
977     }
978   if( selftest_failed )
979     return GPG_ERR_SELFTEST_FAILED;
980
981   if( keylen != 16 )
982     return GPG_ERR_INV_KEYLEN;
983
984   x[0] = buf_get_be32(key + 0);
985   x[1] = buf_get_be32(key + 4);
986   x[2] = buf_get_be32(key + 8);
987   x[3] = buf_get_be32(key + 12);
988
989   key_schedule( x, z, k );
990   for(i=0; i < 16; i++ )
991     c->Km[i] = k[i];
992   key_schedule( x, z, k );
993   for(i=0; i < 16; i++ )
994     c->Kr[i] = k[i] & 0x1f;
995
996 #ifdef USE_ARM_ASM
997   for (i = 0; i < 4; i++)
998     {
999       byte Kr_arm[4];
1000
1001       /* Convert rotate left to rotate right and add shift left
1002        * by 2.  */
1003       Kr_arm[0] = ((32 - c->Kr[4 * i + 0]) - 2) & 0x1f;
1004       Kr_arm[1] = ((32 - c->Kr[4 * i + 1]) - 2) & 0x1f;
1005       Kr_arm[2] = ((32 - c->Kr[4 * i + 2]) - 2) & 0x1f;
1006       Kr_arm[3] = ((32 - c->Kr[4 * i + 3]) - 2) & 0x1f;
1007
1008       /* Endian friendly store.  */
1009       c->Kr_arm_enc[i] = Kr_arm[0] |
1010                         (Kr_arm[1] << 8) |
1011                         (Kr_arm[2] << 16) |
1012                         (Kr_arm[3] << 24);
1013       c->Kr_arm_dec[i] = Kr_arm[3] |
1014                         (Kr_arm[2] << 8) |
1015                         (Kr_arm[1] << 16) |
1016                         (Kr_arm[0] << 24);
1017
1018       wipememory(Kr_arm, sizeof(Kr_arm));
1019     }
1020 #endif
1021
1022   wipememory(x, sizeof x);
1023   wipememory(z, sizeof z);
1024   wipememory(k, sizeof k);
1025
1026 #undef xi
1027 #undef zi
1028   return GPG_ERR_NO_ERROR;
1029 }
1030
1031 static gcry_err_code_t
1032 cast_setkey (void *context, const byte *key, unsigned keylen )
1033 {
1034   CAST5_context *c = (CAST5_context *) context;
1035   gcry_err_code_t rc = do_cast_setkey (c, key, keylen);
1036   return rc;
1037 }
1038
1039
1040 gcry_cipher_spec_t _gcry_cipher_spec_cast5 =
1041   {
1042     GCRY_CIPHER_CAST5, {0, 0},
1043     "CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
1044     cast_setkey, encrypt_block, decrypt_block
1045   };