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