linux/crypto/cast6.c
<<
>>
Prefs
   1/* Kernel cryptographic api.
   2 * cast6.c - Cast6 cipher algorithm [rfc2612].
   3 *
   4 * CAST-256 (*cast6*) is a DES like Substitution-Permutation Network (SPN)
   5 * cryptosystem built upon the CAST-128 (*cast5*) [rfc2144] encryption
   6 * algorithm.
   7 *
   8 * Copyright (C) 2003 Kartikey Mahendra Bhatt <kartik_me@hotmail.com>.
   9 *
  10 * This program is free software; you can redistribute it and/or modify it
  11 * under the terms of GNU General Public License as published by the Free
  12 * Software Foundation; either version 2 of the License, or (at your option)
  13 * any later version.
  14 * 
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  18 */
  19
  20
  21#include <asm/byteorder.h>
  22#include <linux/init.h>
  23#include <linux/crypto.h>
  24#include <linux/module.h>
  25#include <linux/errno.h>
  26#include <linux/string.h>
  27#include <linux/types.h>
  28
  29#define CAST6_BLOCK_SIZE 16
  30#define CAST6_MIN_KEY_SIZE 16
  31#define CAST6_MAX_KEY_SIZE 32
  32
  33struct cast6_ctx {
  34        u32 Km[12][4];
  35        u8 Kr[12][4];
  36};
  37
  38#define F1(D,r,m)  (  (I = ((m) + (D))), (I=rol32(I,(r))),   \
  39    (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
  40#define F2(D,r,m)  (  (I = ((m) ^ (D))), (I=rol32(I,(r))),   \
  41    (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
  42#define F3(D,r,m)  (  (I = ((m) - (D))), (I=rol32(I,(r))),   \
  43    (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
  44
  45static const u32 s1[256] = {
  46        0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
  47        0x9c004dd3, 0x6003e540, 0xcf9fc949,
  48        0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0,
  49        0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
  50        0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3,
  51        0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
  52        0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1,
  53        0xaa54166b, 0x22568e3a, 0xa2d341d0,
  54        0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac,
  55        0x4a97c1d8, 0x527644b7, 0xb5f437a7,
  56        0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0,
  57        0x90ecf52e, 0x22b0c054, 0xbc8e5935,
  58        0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290,
  59        0xe93b159f, 0xb48ee411, 0x4bff345d,
  60        0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad,
  61        0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
  62        0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f,
  63        0xc59c5319, 0xb949e354, 0xb04669fe,
  64        0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5,
  65        0x6a390493, 0xe63d37e0, 0x2a54f6b3,
  66        0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5,
  67        0xf61b1891, 0xbb72275e, 0xaa508167,
  68        0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427,
  69        0xa2d1936b, 0x2ad286af, 0xaa56d291,
  70        0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d,
  71        0x73e2bb14, 0xa0bebc3c, 0x54623779,
  72        0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e,
  73        0x89fe78e6, 0x3fab0950, 0x325ff6c2,
  74        0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf,
  75        0x380782d5, 0xc7fa5cf6, 0x8ac31511,
  76        0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241,
  77        0x051ef495, 0xaa573b04, 0x4a805d8d,
  78        0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b,
  79        0x50afd341, 0xa7c13275, 0x915a0bf5,
  80        0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265,
  81        0xab85c5f3, 0x1b55db94, 0xaad4e324,
  82        0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3,
  83        0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
  84        0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6,
  85        0x22513f1e, 0xaa51a79b, 0x2ad344cc,
  86        0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6,
  87        0x032268d4, 0xc9600acc, 0xce387e6d,
  88        0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da,
  89        0x4736f464, 0x5ad328d8, 0xb347cc96,
  90        0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc,
  91        0xbfc5fe4a, 0xa70aec10, 0xac39570a,
  92        0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f,
  93        0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
  94        0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4,
  95        0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
  96        0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af,
  97        0x51c85f4d, 0x56907596, 0xa5bb15e6,
  98        0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a,
  99        0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
 100        0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf,
 101        0x700b45e1, 0xd5ea50f1, 0x85a92872,
 102        0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198,
 103        0x0cd0ede7, 0x26470db8, 0xf881814c,
 104        0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db,
 105        0xab838653, 0x6e2f1e23, 0x83719c9e,
 106        0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c,
 107        0xe1e696ff, 0xb141ab08, 0x7cca89b9,
 108        0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c,
 109        0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
 110};
 111
 112static const u32 s2[256] = {
 113        0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
 114        0xeec5207a, 0x55889c94, 0x72fc0651,
 115        0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef,
 116        0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
 117        0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086,
 118        0xef944459, 0xba83ccb3, 0xe0c3cdfb,
 119        0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb,
 120        0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
 121        0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f,
 122        0x77e83f4e, 0x79929269, 0x24fa9f7b,
 123        0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154,
 124        0x0d554b63, 0x5d681121, 0xc866c359,
 125        0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181,
 126        0x39f7627f, 0x361e3084, 0xe4eb573b,
 127        0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c,
 128        0x99847ab4, 0xa0e3df79, 0xba6cf38c,
 129        0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a,
 130        0x8f458c74, 0xd9e0a227, 0x4ec73a34,
 131        0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c,
 132        0x1d804366, 0x721d9bfd, 0xa58684bb,
 133        0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1,
 134        0x27e19ba5, 0xd5a6c252, 0xe49754bd,
 135        0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9,
 136        0xe0b56714, 0x21f043b7, 0xe5d05860,
 137        0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf,
 138        0x68561be6, 0x83ca6b94, 0x2d6ed23b,
 139        0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c,
 140        0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
 141        0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122,
 142        0xb96726d1, 0x8049a7e8, 0x22b7da7b,
 143        0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402,
 144        0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
 145        0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53,
 146        0xe3214517, 0xb4542835, 0x9f63293c,
 147        0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6,
 148        0x30a22c95, 0x31a70850, 0x60930f13,
 149        0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6,
 150        0xa02b1741, 0x7cbad9a2, 0x2180036f,
 151        0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676,
 152        0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
 153        0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb,
 154        0x846a3bae, 0x8ff77888, 0xee5d60f6,
 155        0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54,
 156        0x157fd7fa, 0xef8579cc, 0xd152de58,
 157        0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5,
 158        0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
 159        0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8,
 160        0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
 161        0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc,
 162        0x301e16e6, 0x273be979, 0xb0ffeaa6,
 163        0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a,
 164        0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
 165        0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e,
 166        0x1a513742, 0xef6828bc, 0x520365d6,
 167        0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb,
 168        0x5eea29cb, 0x145892f5, 0x91584f7f,
 169        0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4,
 170        0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
 171        0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3,
 172        0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
 173        0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589,
 174        0xa345415e, 0x5c038323, 0x3e5d3bb9,
 175        0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539,
 176        0x73bfbe70, 0x83877605, 0x4523ecf1
 177};
 178
 179static const u32 s3[256] = {
 180        0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
 181        0x369fe44b, 0x8c1fc644, 0xaececa90,
 182        0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806,
 183        0xf0ad0548, 0xe13c8d83, 0x927010d5,
 184        0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820,
 185        0xfade82e0, 0xa067268b, 0x8272792e,
 186        0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee,
 187        0x825b1bfd, 0x9255c5ed, 0x1257a240,
 188        0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf,
 189        0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
 190        0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1,
 191        0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
 192        0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c,
 193        0x4a012d6e, 0xc5884a28, 0xccc36f71,
 194        0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850,
 195        0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
 196        0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e,
 197        0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
 198        0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0,
 199        0x1eac5790, 0x796fb449, 0x8252dc15,
 200        0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403,
 201        0xe83ec305, 0x4f91751a, 0x925669c2,
 202        0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574,
 203        0x927985b2, 0x8276dbcb, 0x02778176,
 204        0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83,
 205        0x340ce5c8, 0x96bbb682, 0x93b4b148,
 206        0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20,
 207        0x8437aa88, 0x7d29dc96, 0x2756d3dc,
 208        0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e,
 209        0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
 210        0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9,
 211        0xbda8229c, 0x127dadaa, 0x438a074e,
 212        0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff,
 213        0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
 214        0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a,
 215        0x76a2e214, 0xb9a40368, 0x925d958f,
 216        0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623,
 217        0x193cbcfa, 0x27627545, 0x825cf47a,
 218        0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7,
 219        0x8272a972, 0x9270c4a8, 0x127de50b,
 220        0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb,
 221        0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
 222        0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11,
 223        0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
 224        0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c,
 225        0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
 226        0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40,
 227        0x7c34671c, 0x02717ef6, 0x4feb5536,
 228        0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1,
 229        0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
 230        0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33,
 231        0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
 232        0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff,
 233        0x856302e0, 0x72dbd92b, 0xee971b69,
 234        0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2,
 235        0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
 236        0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38,
 237        0x0ff0443d, 0x606e6dc6, 0x60543a49,
 238        0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f,
 239        0x68458425, 0x99833be5, 0x600d457d,
 240        0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31,
 241        0x9c305a00, 0x52bce688, 0x1b03588a,
 242        0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636,
 243        0xa133c501, 0xe9d3531c, 0xee353783
 244};
 245
 246static const u32 s4[256] = {
 247        0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
 248        0x64ad8c57, 0x85510443, 0xfa020ed1,
 249        0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43,
 250        0x6497b7b1, 0xf3641f63, 0x241e4adf,
 251        0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30,
 252        0xc0a5374f, 0x1d2d00d9, 0x24147b15,
 253        0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f,
 254        0x0c13fefe, 0x081b08ca, 0x05170121,
 255        0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f,
 256        0x06df4261, 0xbb9e9b8a, 0x7293ea25,
 257        0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400,
 258        0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
 259        0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061,
 260        0x11b638e1, 0x72500e03, 0xf80eb2bb,
 261        0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400,
 262        0x6920318f, 0x081dbb99, 0xffc304a5,
 263        0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea,
 264        0x9f926f91, 0x9f46222f, 0x3991467d,
 265        0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8,
 266        0x3fb6180c, 0x18f8931e, 0x281658e6,
 267        0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25,
 268        0x79098b02, 0xe4eabb81, 0x28123b23,
 269        0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9,
 270        0x0014377b, 0x041e8ac8, 0x09114003,
 271        0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de,
 272        0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
 273        0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0,
 274        0x56c8c391, 0x6b65811c, 0x5e146119,
 275        0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d,
 276        0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
 277        0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a,
 278        0xeca1d7c7, 0x041afa32, 0x1d16625a,
 279        0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb,
 280        0xc70b8b46, 0xd9e66a48, 0x56e55a79,
 281        0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3,
 282        0xedda04eb, 0x17a9be04, 0x2c18f4df,
 283        0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254,
 284        0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
 285        0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2,
 286        0x0418f2c8, 0x001a96a6, 0x0d1526ab,
 287        0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86,
 288        0x311170a7, 0x3e9b640c, 0xcc3e10d7,
 289        0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1,
 290        0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
 291        0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca,
 292        0xb4be31cd, 0xd8782806, 0x12a3a4e2,
 293        0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5,
 294        0x9711aac5, 0x001d7b95, 0x82e5e7d2,
 295        0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415,
 296        0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
 297        0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7,
 298        0x0ce454a9, 0xd60acd86, 0x015f1919,
 299        0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe,
 300        0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
 301        0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb,
 302        0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
 303        0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8,
 304        0x296b299e, 0x492fc295, 0x9266beab,
 305        0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee,
 306        0xf65324e6, 0x6afce36c, 0x0316cc04,
 307        0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979,
 308        0x932bcdf6, 0xb657c34d, 0x4edfd282,
 309        0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0,
 310        0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
 311};
 312
 313static const u32 Tm[24][8] = {
 314        { 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d,
 315                0x84c413be, 0xf39dff5f, 0x6277eb00 } , 
 316        { 0xd151d6a1, 0x402bc242, 0xaf05ade3, 0x1ddf9984, 0x8cb98525,
 317                0xfb9370c6, 0x6a6d5c67, 0xd9474808 } ,
 318        { 0x482133a9, 0xb6fb1f4a, 0x25d50aeb, 0x94aef68c, 0x0388e22d,
 319                0x7262cdce, 0xe13cb96f, 0x5016a510 } ,
 320        { 0xbef090b1, 0x2dca7c52, 0x9ca467f3, 0x0b7e5394, 0x7a583f35,
 321                0xe9322ad6, 0x580c1677, 0xc6e60218 } ,
 322        { 0x35bfedb9, 0xa499d95a, 0x1373c4fb, 0x824db09c, 0xf1279c3d,
 323                0x600187de, 0xcedb737f, 0x3db55f20 } ,
 324        { 0xac8f4ac1, 0x1b693662, 0x8a432203, 0xf91d0da4, 0x67f6f945,
 325                0xd6d0e4e6, 0x45aad087, 0xb484bc28 } ,
 326        { 0x235ea7c9, 0x9238936a, 0x01127f0b, 0x6fec6aac, 0xdec6564d,
 327                0x4da041ee, 0xbc7a2d8f, 0x2b541930 } ,
 328        { 0x9a2e04d1, 0x0907f072, 0x77e1dc13, 0xe6bbc7b4, 0x5595b355,
 329                0xc46f9ef6, 0x33498a97, 0xa2237638 } ,
 330        { 0x10fd61d9, 0x7fd74d7a, 0xeeb1391b, 0x5d8b24bc, 0xcc65105d,
 331                0x3b3efbfe, 0xaa18e79f, 0x18f2d340 } ,
 332        { 0x87ccbee1, 0xf6a6aa82, 0x65809623, 0xd45a81c4, 0x43346d65,
 333                0xb20e5906, 0x20e844a7, 0x8fc23048 } ,
 334        { 0xfe9c1be9, 0x6d76078a, 0xdc4ff32b, 0x4b29decc, 0xba03ca6d,
 335                0x28ddb60e, 0x97b7a1af, 0x06918d50 } ,
 336        { 0x756b78f1, 0xe4456492, 0x531f5033, 0xc1f93bd4, 0x30d32775,
 337                0x9fad1316, 0x0e86feb7, 0x7d60ea58 } ,
 338        { 0xec3ad5f9, 0x5b14c19a, 0xc9eead3b, 0x38c898dc, 0xa7a2847d,
 339                0x167c701e, 0x85565bbf, 0xf4304760 } ,
 340        { 0x630a3301, 0xd1e41ea2, 0x40be0a43, 0xaf97f5e4, 0x1e71e185,
 341                0x8d4bcd26, 0xfc25b8c7, 0x6affa468 } ,
 342        { 0xd9d99009, 0x48b37baa, 0xb78d674b, 0x266752ec, 0x95413e8d,
 343                0x041b2a2e, 0x72f515cf, 0xe1cf0170 } ,
 344        { 0x50a8ed11, 0xbf82d8b2, 0x2e5cc453, 0x9d36aff4, 0x0c109b95,
 345                0x7aea8736, 0xe9c472d7, 0x589e5e78 } ,
 346        { 0xc7784a19, 0x365235ba, 0xa52c215b, 0x14060cfc, 0x82dff89d,
 347                0xf1b9e43e, 0x6093cfdf, 0xcf6dbb80 } ,
 348        { 0x3e47a721, 0xad2192c2, 0x1bfb7e63, 0x8ad56a04, 0xf9af55a5,
 349                0x68894146, 0xd7632ce7, 0x463d1888 } ,
 350        { 0xb5170429, 0x23f0efca, 0x92cadb6b, 0x01a4c70c, 0x707eb2ad,
 351                0xdf589e4e, 0x4e3289ef, 0xbd0c7590 } ,
 352        { 0x2be66131, 0x9ac04cd2, 0x099a3873, 0x78742414, 0xe74e0fb5,
 353                0x5627fb56, 0xc501e6f7, 0x33dbd298 } ,
 354        { 0xa2b5be39, 0x118fa9da, 0x8069957b, 0xef43811c, 0x5e1d6cbd,
 355                0xccf7585e, 0x3bd143ff, 0xaaab2fa0 } ,
 356        { 0x19851b41, 0x885f06e2, 0xf738f283, 0x6612de24, 0xd4ecc9c5,
 357                0x43c6b566, 0xb2a0a107, 0x217a8ca8 } ,
 358        { 0x90547849, 0xff2e63ea, 0x6e084f8b, 0xdce23b2c, 0x4bbc26cd,
 359                0xba96126e, 0x296ffe0f, 0x9849e9b0 } ,
 360        { 0x0723d551, 0x75fdc0f2, 0xe4d7ac93, 0x53b19834, 0xc28b83d5,
 361                0x31656f76, 0xa03f5b17, 0x0f1946b8 }
 362};
 363
 364static const u8 Tr[4][8] = {
 365        { 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0a } ,
 366        { 0x1b, 0x0c, 0x1d, 0x0e, 0x1f, 0x10, 0x01, 0x12 } ,
 367        { 0x03, 0x14, 0x05, 0x16, 0x07, 0x18, 0x09, 0x1a } ,
 368        { 0x0b, 0x1c, 0x0d, 0x1e, 0x0f, 0x00, 0x11, 0x02 }
 369};
 370
 371/* forward octave */
 372static void W(u32 *key, unsigned int i) {
 373        u32 I;
 374        key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]);
 375        key[5] ^= F2(key[6], Tr[i % 4][1], Tm[i][1]);
 376        key[4] ^= F3(key[5], Tr[i % 4][2], Tm[i][2]);
 377        key[3] ^= F1(key[4], Tr[i % 4][3], Tm[i][3]);
 378        key[2] ^= F2(key[3], Tr[i % 4][4], Tm[i][4]);
 379        key[1] ^= F3(key[2], Tr[i % 4][5], Tm[i][5]);
 380        key[0] ^= F1(key[1], Tr[i % 4][6], Tm[i][6]);   
 381        key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]);
 382}
 383
 384static int cast6_setkey(struct crypto_tfm *tfm, const u8 *in_key,
 385                        unsigned key_len)
 386{
 387        int i;
 388        u32 key[8];
 389        __be32 p_key[8]; /* padded key */
 390        struct cast6_ctx *c = crypto_tfm_ctx(tfm);
 391        u32 *flags = &tfm->crt_flags;
 392
 393        if (key_len % 4 != 0) {
 394                *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
 395                return -EINVAL;
 396        }       
 397
 398        memset (p_key, 0, 32);
 399        memcpy (p_key, in_key, key_len);
 400        
 401        key[0] = be32_to_cpu(p_key[0]);         /* A */
 402        key[1] = be32_to_cpu(p_key[1]);         /* B */
 403        key[2] = be32_to_cpu(p_key[2]);         /* C */
 404        key[3] = be32_to_cpu(p_key[3]);         /* D */
 405        key[4] = be32_to_cpu(p_key[4]);         /* E */
 406        key[5] = be32_to_cpu(p_key[5]);         /* F */
 407        key[6] = be32_to_cpu(p_key[6]);         /* G */
 408        key[7] = be32_to_cpu(p_key[7]);         /* H */
 409        
 410
 411
 412        for (i = 0; i < 12; i++) {
 413                W (key, 2 * i);
 414                W (key, 2 * i + 1);
 415                
 416                c->Kr[i][0] = key[0] & 0x1f;
 417                c->Kr[i][1] = key[2] & 0x1f;
 418                c->Kr[i][2] = key[4] & 0x1f;
 419                c->Kr[i][3] = key[6] & 0x1f;
 420                
 421                c->Km[i][0] = key[7];
 422                c->Km[i][1] = key[5];
 423                c->Km[i][2] = key[3];
 424                c->Km[i][3] = key[1];
 425        }
 426
 427        return 0;
 428}
 429
 430/*forward quad round*/
 431static void Q (u32 * block, u8 * Kr, u32 * Km) {
 432        u32 I;
 433        block[2] ^= F1(block[3], Kr[0], Km[0]);
 434        block[1] ^= F2(block[2], Kr[1], Km[1]);
 435        block[0] ^= F3(block[1], Kr[2], Km[2]);
 436        block[3] ^= F1(block[0], Kr[3], Km[3]);         
 437}
 438
 439/*reverse quad round*/
 440static void QBAR (u32 * block, u8 * Kr, u32 * Km) {
 441        u32 I;
 442        block[3] ^= F1(block[0], Kr[3], Km[3]);
 443        block[0] ^= F3(block[1], Kr[2], Km[2]);
 444        block[1] ^= F2(block[2], Kr[1], Km[1]);
 445        block[2] ^= F1(block[3], Kr[0], Km[0]);
 446}
 447
 448static void cast6_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
 449{
 450        struct cast6_ctx *c = crypto_tfm_ctx(tfm);
 451        const __be32 *src = (const __be32 *)inbuf;
 452        __be32 *dst = (__be32 *)outbuf;
 453        u32 block[4];
 454        u32 * Km; 
 455        u8 * Kr;
 456
 457        block[0] = be32_to_cpu(src[0]);
 458        block[1] = be32_to_cpu(src[1]);
 459        block[2] = be32_to_cpu(src[2]);
 460        block[3] = be32_to_cpu(src[3]);
 461
 462        Km = c->Km[0]; Kr = c->Kr[0]; Q (block, Kr, Km);
 463        Km = c->Km[1]; Kr = c->Kr[1]; Q (block, Kr, Km);
 464        Km = c->Km[2]; Kr = c->Kr[2]; Q (block, Kr, Km);
 465        Km = c->Km[3]; Kr = c->Kr[3]; Q (block, Kr, Km);
 466        Km = c->Km[4]; Kr = c->Kr[4]; Q (block, Kr, Km);
 467        Km = c->Km[5]; Kr = c->Kr[5]; Q (block, Kr, Km);
 468        Km = c->Km[6]; Kr = c->Kr[6]; QBAR (block, Kr, Km);
 469        Km = c->Km[7]; Kr = c->Kr[7]; QBAR (block, Kr, Km);
 470        Km = c->Km[8]; Kr = c->Kr[8]; QBAR (block, Kr, Km);
 471        Km = c->Km[9]; Kr = c->Kr[9]; QBAR (block, Kr, Km);
 472        Km = c->Km[10]; Kr = c->Kr[10]; QBAR (block, Kr, Km);
 473        Km = c->Km[11]; Kr = c->Kr[11]; QBAR (block, Kr, Km);
 474
 475        dst[0] = cpu_to_be32(block[0]);
 476        dst[1] = cpu_to_be32(block[1]);
 477        dst[2] = cpu_to_be32(block[2]);
 478        dst[3] = cpu_to_be32(block[3]);
 479}       
 480
 481static void cast6_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) {
 482        struct cast6_ctx * c = crypto_tfm_ctx(tfm);
 483        const __be32 *src = (const __be32 *)inbuf;
 484        __be32 *dst = (__be32 *)outbuf;
 485        u32 block[4];
 486        u32 * Km; 
 487        u8 * Kr;
 488
 489        block[0] = be32_to_cpu(src[0]);
 490        block[1] = be32_to_cpu(src[1]);
 491        block[2] = be32_to_cpu(src[2]);
 492        block[3] = be32_to_cpu(src[3]);
 493
 494        Km = c->Km[11]; Kr = c->Kr[11]; Q (block, Kr, Km);
 495        Km = c->Km[10]; Kr = c->Kr[10]; Q (block, Kr, Km);
 496        Km = c->Km[9]; Kr = c->Kr[9]; Q (block, Kr, Km);
 497        Km = c->Km[8]; Kr = c->Kr[8]; Q (block, Kr, Km);
 498        Km = c->Km[7]; Kr = c->Kr[7]; Q (block, Kr, Km);
 499        Km = c->Km[6]; Kr = c->Kr[6]; Q (block, Kr, Km);
 500        Km = c->Km[5]; Kr = c->Kr[5]; QBAR (block, Kr, Km);
 501        Km = c->Km[4]; Kr = c->Kr[4]; QBAR (block, Kr, Km);
 502        Km = c->Km[3]; Kr = c->Kr[3]; QBAR (block, Kr, Km);
 503        Km = c->Km[2]; Kr = c->Kr[2]; QBAR (block, Kr, Km);
 504        Km = c->Km[1]; Kr = c->Kr[1]; QBAR (block, Kr, Km);
 505        Km = c->Km[0]; Kr = c->Kr[0]; QBAR (block, Kr, Km);
 506        
 507        dst[0] = cpu_to_be32(block[0]);
 508        dst[1] = cpu_to_be32(block[1]);
 509        dst[2] = cpu_to_be32(block[2]);
 510        dst[3] = cpu_to_be32(block[3]);
 511}       
 512
 513static struct crypto_alg alg = {
 514        .cra_name = "cast6",
 515        .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
 516        .cra_blocksize = CAST6_BLOCK_SIZE,
 517        .cra_ctxsize = sizeof(struct cast6_ctx),
 518        .cra_alignmask = 3,
 519        .cra_module = THIS_MODULE,
 520        .cra_list = LIST_HEAD_INIT(alg.cra_list),
 521        .cra_u = {
 522                  .cipher = {
 523                             .cia_min_keysize = CAST6_MIN_KEY_SIZE,
 524                             .cia_max_keysize = CAST6_MAX_KEY_SIZE,
 525                             .cia_setkey = cast6_setkey,
 526                             .cia_encrypt = cast6_encrypt,
 527                             .cia_decrypt = cast6_decrypt}
 528                  }
 529};
 530
 531static int __init cast6_mod_init(void)
 532{
 533        return crypto_register_alg(&alg);
 534}
 535
 536static void __exit cast6_mod_fini(void)
 537{
 538        crypto_unregister_alg(&alg);
 539}
 540
 541module_init(cast6_mod_init);
 542module_exit(cast6_mod_fini);
 543
 544MODULE_LICENSE("GPL");
 545MODULE_DESCRIPTION("Cast6 Cipher Algorithm");
 546