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                                     cipher_bulk_ops_t *bulk_ops);
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
do_encrypt_block(CAST5_context * context,byte * outbuf,const byte * inbuf)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
do_decrypt_block(CAST5_context * context,byte * outbuf,const byte * inbuf)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
cast5_amd64_ctr_enc(CAST5_context * ctx,byte * out,const byte * in,byte * ctr)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
cast5_amd64_cbc_dec(CAST5_context * ctx,byte * out,const byte * in,byte * iv)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
cast5_amd64_cfb_dec(CAST5_context * ctx,byte * out,const byte * in,byte * iv)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
encrypt_block(void * context,byte * outbuf,const byte * inbuf)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
decrypt_block(void * context,byte * outbuf,const byte * inbuf)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
do_encrypt_block(CAST5_context * context,byte * outbuf,const byte * inbuf)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
do_decrypt_block(CAST5_context * context,byte * outbuf,const byte * inbuf)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
encrypt_block(void * context,byte * outbuf,const byte * inbuf)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
decrypt_block(void * context,byte * outbuf,const byte * inbuf)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
do_encrypt_block(CAST5_context * c,byte * outbuf,const byte * inbuf)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
encrypt_block(void * context,byte * outbuf,const byte * inbuf)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
do_encrypt_block_3(CAST5_context * c,byte * outbuf,const byte * inbuf)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
do_decrypt_block(CAST5_context * c,byte * outbuf,const byte * inbuf)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
decrypt_block(void * context,byte * outbuf,const byte * inbuf)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
do_decrypt_block_3(CAST5_context * c,byte * outbuf,const byte * inbuf)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 static void
_gcry_cast5_ctr_enc(void * context,unsigned char * ctr,void * outbuf_arg,const void * inbuf_arg,size_t nblocks)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 static void
_gcry_cast5_cbc_dec(void * context,unsigned char * iv,void * outbuf_arg,const void * inbuf_arg,size_t nblocks)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 static void
_gcry_cast5_cfb_dec(void * context,unsigned char * iv,void * outbuf_arg,const void * inbuf_arg,size_t nblocks)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 *
selftest_ctr(void)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, nblocks, blocksize, context_size);
1005 }
1006 
1007 
1008 /* Run the self-tests for CAST5-CBC, tests bulk CBC decryption.
1009    Returns NULL on success. */
1010 static const char *
selftest_cbc(void)1011 selftest_cbc (void)
1012 {
1013   const int nblocks = 4+2;
1014   const int blocksize = CAST5_BLOCKSIZE;
1015   const int context_size = sizeof(CAST5_context);
1016 
1017   return _gcry_selftest_helper_cbc("CAST5", &cast_setkey,
1018            &encrypt_block, nblocks, blocksize, context_size);
1019 }
1020 
1021 
1022 /* Run the self-tests for CAST5-CFB, tests bulk CBC decryption.
1023    Returns NULL on success. */
1024 static const char *
selftest_cfb(void)1025 selftest_cfb (void)
1026 {
1027   const int nblocks = 4+2;
1028   const int blocksize = CAST5_BLOCKSIZE;
1029   const int context_size = sizeof(CAST5_context);
1030 
1031   return _gcry_selftest_helper_cfb("CAST5", &cast_setkey,
1032            &encrypt_block, nblocks, blocksize, context_size);
1033 }
1034 
1035 
1036 static const char*
selftest(void)1037 selftest(void)
1038 {
1039     CAST5_context c;
1040     cipher_bulk_ops_t bulk_ops;
1041     static const byte key[16] =
1042                     { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
1043 		      0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A  };
1044     static const byte plain[8] =
1045                     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
1046     static const byte cipher[8] =
1047                     { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
1048     byte buffer[8];
1049     const char *r;
1050 
1051     cast_setkey( &c, key, 16, &bulk_ops );
1052     encrypt_block( &c, buffer, plain );
1053     if( memcmp( buffer, cipher, 8 ) )
1054 	return "1";
1055     decrypt_block( &c, buffer, buffer );
1056     if( memcmp( buffer, plain, 8 ) )
1057 	return "2";
1058 
1059 #if 0 /* full maintenance test */
1060     {
1061 	int i;
1062 	byte a0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
1063 			0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
1064 	byte b0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
1065 			0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
1066 	byte a1[16] = { 0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
1067 			0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92 };
1068 	byte b1[16] = { 0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
1069 			0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E };
1070 
1071 	for(i=0; i < 1000000; i++ ) {
1072 	    cast_setkey( &c, b0, 16, &bulk_ops );
1073 	    encrypt_block( &c, a0, a0 );
1074 	    encrypt_block( &c, a0+8, a0+8 );
1075 	    cast_setkey( &c, a0, 16, &bulk_ops );
1076 	    encrypt_block( &c, b0, b0 );
1077 	    encrypt_block( &c, b0+8, b0+8 );
1078 	}
1079 	if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) )
1080 	    return "3";
1081 
1082     }
1083 #endif
1084 
1085     if ( (r = selftest_cbc ()) )
1086       return r;
1087 
1088     if ( (r = selftest_cfb ()) )
1089       return r;
1090 
1091     if ( (r = selftest_ctr ()) )
1092       return r;
1093 
1094     return NULL;
1095 }
1096 
1097 
1098 static void
key_schedule(u32 * x,u32 * z,u32 * k)1099 key_schedule( u32 *x, u32 *z, u32 *k )
1100 {
1101 
1102 #define xi(i)   ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
1103 #define zi(i)   ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
1104 
1105     z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
1106     z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
1107     z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
1108     z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
1109     k[0] = s5[zi( 8)]^s6[zi( 9)]^s7[zi( 7)]^s8[zi( 6)]^s5[zi( 2)];
1110     k[1] = s5[zi(10)]^s6[zi(11)]^s7[zi( 5)]^s8[zi( 4)]^s6[zi( 6)];
1111     k[2] = s5[zi(12)]^s6[zi(13)]^s7[zi( 3)]^s8[zi( 2)]^s7[zi( 9)];
1112     k[3] = s5[zi(14)]^s6[zi(15)]^s7[zi( 1)]^s8[zi( 0)]^s8[zi(12)];
1113 
1114     x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
1115     x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
1116     x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
1117     x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
1118     k[4] = s5[xi( 3)]^s6[xi( 2)]^s7[xi(12)]^s8[xi(13)]^s5[xi( 8)];
1119     k[5] = s5[xi( 1)]^s6[xi( 0)]^s7[xi(14)]^s8[xi(15)]^s6[xi(13)];
1120     k[6] = s5[xi( 7)]^s6[xi( 6)]^s7[xi( 8)]^s8[xi( 9)]^s7[xi( 3)];
1121     k[7] = s5[xi( 5)]^s6[xi( 4)]^s7[xi(10)]^s8[xi(11)]^s8[xi( 7)];
1122 
1123     z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
1124     z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
1125     z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
1126     z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
1127     k[8] = s5[zi( 3)]^s6[zi( 2)]^s7[zi(12)]^s8[zi(13)]^s5[zi( 9)];
1128     k[9] = s5[zi( 1)]^s6[zi( 0)]^s7[zi(14)]^s8[zi(15)]^s6[zi(12)];
1129     k[10]= s5[zi( 7)]^s6[zi( 6)]^s7[zi( 8)]^s8[zi( 9)]^s7[zi( 2)];
1130     k[11]= s5[zi( 5)]^s6[zi( 4)]^s7[zi(10)]^s8[zi(11)]^s8[zi( 6)];
1131 
1132     x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
1133     x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
1134     x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
1135     x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
1136     k[12]= s5[xi( 8)]^s6[xi( 9)]^s7[xi( 7)]^s8[xi( 6)]^s5[xi( 3)];
1137     k[13]= s5[xi(10)]^s6[xi(11)]^s7[xi( 5)]^s8[xi( 4)]^s6[xi( 7)];
1138     k[14]= s5[xi(12)]^s6[xi(13)]^s7[xi( 3)]^s8[xi( 2)]^s7[xi( 8)];
1139     k[15]= s5[xi(14)]^s6[xi(15)]^s7[xi( 1)]^s8[xi( 0)]^s8[xi(13)];
1140 
1141 #undef xi
1142 #undef zi
1143 }
1144 
1145 
1146 static gcry_err_code_t
do_cast_setkey(CAST5_context * c,const byte * key,unsigned keylen)1147 do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
1148 {
1149   static int initialized;
1150   static const char* selftest_failed;
1151   int i;
1152   u32 x[4];
1153   u32 z[4];
1154   u32 k[16];
1155 
1156   if( !initialized )
1157     {
1158       initialized = 1;
1159       selftest_failed = selftest();
1160       if( selftest_failed )
1161         log_error ("CAST5 selftest failed (%s).\n", selftest_failed );
1162     }
1163   if( selftest_failed )
1164     return GPG_ERR_SELFTEST_FAILED;
1165 
1166   if( keylen != 16 )
1167     return GPG_ERR_INV_KEYLEN;
1168 
1169   x[0] = buf_get_be32(key + 0);
1170   x[1] = buf_get_be32(key + 4);
1171   x[2] = buf_get_be32(key + 8);
1172   x[3] = buf_get_be32(key + 12);
1173 
1174   key_schedule( x, z, k );
1175   for(i=0; i < 16; i++ )
1176     c->Km[i] = k[i];
1177   key_schedule( x, z, k );
1178   for(i=0; i < 16; i++ )
1179     c->Kr[i] = k[i] & 0x1f;
1180 
1181 #ifdef USE_ARM_ASM
1182   for (i = 0; i < 4; i++)
1183     {
1184       byte Kr_arm[4];
1185 
1186       /* Convert rotate left to rotate right and add shift left
1187        * by 2.  */
1188       Kr_arm[0] = ((32 - c->Kr[4 * i + 0]) - 2) & 0x1f;
1189       Kr_arm[1] = ((32 - c->Kr[4 * i + 1]) - 2) & 0x1f;
1190       Kr_arm[2] = ((32 - c->Kr[4 * i + 2]) - 2) & 0x1f;
1191       Kr_arm[3] = ((32 - c->Kr[4 * i + 3]) - 2) & 0x1f;
1192 
1193       /* Endian friendly store.  */
1194       c->Kr_arm_enc[i] = Kr_arm[0] |
1195                         (Kr_arm[1] << 8) |
1196                         (Kr_arm[2] << 16) |
1197                         (Kr_arm[3] << 24);
1198       c->Kr_arm_dec[i] = Kr_arm[3] |
1199                         (Kr_arm[2] << 8) |
1200                         (Kr_arm[1] << 16) |
1201                         (Kr_arm[0] << 24);
1202 
1203       wipememory(Kr_arm, sizeof(Kr_arm));
1204     }
1205 #endif
1206 
1207   wipememory(x, sizeof x);
1208   wipememory(z, sizeof z);
1209   wipememory(k, sizeof k);
1210 
1211 #undef xi
1212 #undef zi
1213   return GPG_ERR_NO_ERROR;
1214 }
1215 
1216 static gcry_err_code_t
cast_setkey(void * context,const byte * key,unsigned keylen,cipher_bulk_ops_t * bulk_ops)1217 cast_setkey (void *context, const byte *key, unsigned keylen,
1218              cipher_bulk_ops_t *bulk_ops)
1219 {
1220   CAST5_context *c = (CAST5_context *) context;
1221   gcry_err_code_t rc = do_cast_setkey (c, key, keylen);
1222 
1223   /* Setup bulk encryption routines.  */
1224   memset (bulk_ops, 0, sizeof(*bulk_ops));
1225   bulk_ops->cfb_dec = _gcry_cast5_cfb_dec;
1226   bulk_ops->cbc_dec = _gcry_cast5_cbc_dec;
1227   bulk_ops->ctr_enc = _gcry_cast5_ctr_enc;
1228 
1229   return rc;
1230 }
1231 
1232 
1233 gcry_cipher_spec_t _gcry_cipher_spec_cast5 =
1234   {
1235     GCRY_CIPHER_CAST5, {0, 0},
1236     "CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
1237     cast_setkey, encrypt_block, decrypt_block
1238   };
1239