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