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