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