RHEL5/crypto/serpent.c
<<
>>
Prefs
   1/*
   2 * Cryptographic API.
   3 *
   4 * Serpent Cipher Algorithm.
   5 *
   6 * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
   7 *               2003 Herbert Valerio Riedel <hvr@gnu.org>
   8 *
   9 * Added tnepres support: Ruben Jesus Garcia Hernandez <ruben@ugr.es>, 18.10.2004
  10 *               Based on code by hvr
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License as published by
  14 * the Free Software Foundation; either version 2 of the License, or
  15 * (at your option) any later version.
  16 */
  17
  18#include <linux/init.h>
  19#include <linux/module.h>
  20#include <linux/errno.h>
  21#include <asm/byteorder.h>
  22#include <linux/crypto.h>
  23#include <linux/types.h>
  24
  25/* Key is padded to the maximum of 256 bits before round key generation.
  26 * Any key length <= 256 bits (32 bytes) is allowed by the algorithm.
  27 */
  28
  29#define SERPENT_MIN_KEY_SIZE              0
  30#define SERPENT_MAX_KEY_SIZE             32
  31#define SERPENT_EXPKEY_WORDS            132
  32#define SERPENT_BLOCK_SIZE               16
  33
  34#define PHI 0x9e3779b9UL
  35
  36#define keyiter(a,b,c,d,i,j) \
  37        b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; b = rol32(b,11); k[j] = b;
  38
  39#define loadkeys(x0,x1,x2,x3,i) \
  40        x0=k[i]; x1=k[i+1]; x2=k[i+2]; x3=k[i+3];
  41
  42#define storekeys(x0,x1,x2,x3,i) \
  43        k[i]=x0; k[i+1]=x1; k[i+2]=x2; k[i+3]=x3;
  44
  45#define K(x0,x1,x2,x3,i)                                \
  46        x3 ^= k[4*(i)+3];        x2 ^= k[4*(i)+2];      \
  47        x1 ^= k[4*(i)+1];        x0 ^= k[4*(i)+0];
  48
  49#define LK(x0,x1,x2,x3,x4,i)                            \
  50                                        x0=rol32(x0,13);\
  51        x2=rol32(x2,3); x1 ^= x0;       x4  = x0 << 3;  \
  52        x3 ^= x2;       x1 ^= x2;                       \
  53        x1=rol32(x1,1); x3 ^= x4;                       \
  54        x3=rol32(x3,7); x4  = x1;                       \
  55        x0 ^= x1;       x4 <<= 7;       x2 ^= x3;       \
  56        x0 ^= x3;       x2 ^= x4;       x3 ^= k[4*i+3]; \
  57        x1 ^= k[4*i+1]; x0=rol32(x0,5); x2=rol32(x2,22);\
  58        x0 ^= k[4*i+0]; x2 ^= k[4*i+2];
  59
  60#define KL(x0,x1,x2,x3,x4,i)                            \
  61        x0 ^= k[4*i+0]; x1 ^= k[4*i+1]; x2 ^= k[4*i+2]; \
  62        x3 ^= k[4*i+3]; x0=ror32(x0,5); x2=ror32(x2,22);\
  63        x4 =  x1;       x2 ^= x3;       x0 ^= x3;       \
  64        x4 <<= 7;       x0 ^= x1;       x1=ror32(x1,1); \
  65        x2 ^= x4;       x3=ror32(x3,7); x4 = x0 << 3;   \
  66        x1 ^= x0;       x3 ^= x4;       x0=ror32(x0,13);\
  67        x1 ^= x2;       x3 ^= x2;       x2=ror32(x2,3);
  68
  69#define S0(x0,x1,x2,x3,x4)                              \
  70                                        x4  = x3;       \
  71        x3 |= x0;       x0 ^= x4;       x4 ^= x2;       \
  72        x4 =~ x4;       x3 ^= x1;       x1 &= x0;       \
  73        x1 ^= x4;       x2 ^= x0;       x0 ^= x3;       \
  74        x4 |= x0;       x0 ^= x2;       x2 &= x1;       \
  75        x3 ^= x2;       x1 =~ x1;       x2 ^= x4;       \
  76        x1 ^= x2;
  77
  78#define S1(x0,x1,x2,x3,x4)                              \
  79                                        x4  = x1;       \
  80        x1 ^= x0;       x0 ^= x3;       x3 =~ x3;       \
  81        x4 &= x1;       x0 |= x1;       x3 ^= x2;       \
  82        x0 ^= x3;       x1 ^= x3;       x3 ^= x4;       \
  83        x1 |= x4;       x4 ^= x2;       x2 &= x0;       \
  84        x2 ^= x1;       x1 |= x0;       x0 =~ x0;       \
  85        x0 ^= x2;       x4 ^= x1;
  86
  87#define S2(x0,x1,x2,x3,x4)                              \
  88                                        x3 =~ x3;       \
  89        x1 ^= x0;       x4  = x0;       x0 &= x2;       \
  90        x0 ^= x3;       x3 |= x4;       x2 ^= x1;       \
  91        x3 ^= x1;       x1 &= x0;       x0 ^= x2;       \
  92        x2 &= x3;       x3 |= x1;       x0 =~ x0;       \
  93        x3 ^= x0;       x4 ^= x0;       x0 ^= x2;       \
  94        x1 |= x2;
  95
  96#define S3(x0,x1,x2,x3,x4)                              \
  97                                        x4  = x1;       \
  98        x1 ^= x3;       x3 |= x0;       x4 &= x0;       \
  99        x0 ^= x2;       x2 ^= x1;       x1 &= x3;       \
 100        x2 ^= x3;       x0 |= x4;       x4 ^= x3;       \
 101        x1 ^= x0;       x0 &= x3;       x3 &= x4;       \
 102        x3 ^= x2;       x4 |= x1;       x2 &= x1;       \
 103        x4 ^= x3;       x0 ^= x3;       x3 ^= x2;
 104
 105#define S4(x0,x1,x2,x3,x4)                              \
 106                                        x4  = x3;       \
 107        x3 &= x0;       x0 ^= x4;                       \
 108        x3 ^= x2;       x2 |= x4;       x0 ^= x1;       \
 109        x4 ^= x3;       x2 |= x0;                       \
 110        x2 ^= x1;       x1 &= x0;                       \
 111        x1 ^= x4;       x4 &= x2;       x2 ^= x3;       \
 112        x4 ^= x0;       x3 |= x1;       x1 =~ x1;       \
 113        x3 ^= x0;
 114
 115#define S5(x0,x1,x2,x3,x4)                              \
 116        x4  = x1;       x1 |= x0;                       \
 117        x2 ^= x1;       x3 =~ x3;       x4 ^= x0;       \
 118        x0 ^= x2;       x1 &= x4;       x4 |= x3;       \
 119        x4 ^= x0;       x0 &= x3;       x1 ^= x3;       \
 120        x3 ^= x2;       x0 ^= x1;       x2 &= x4;       \
 121        x1 ^= x2;       x2 &= x0;                       \
 122        x3 ^= x2;
 123
 124#define S6(x0,x1,x2,x3,x4)                              \
 125                                        x4  = x1;       \
 126        x3 ^= x0;       x1 ^= x2;       x2 ^= x0;       \
 127        x0 &= x3;       x1 |= x3;       x4 =~ x4;       \
 128        x0 ^= x1;       x1 ^= x2;                       \
 129        x3 ^= x4;       x4 ^= x0;       x2 &= x0;       \
 130        x4 ^= x1;       x2 ^= x3;       x3 &= x1;       \
 131        x3 ^= x0;       x1 ^= x2;
 132
 133#define S7(x0,x1,x2,x3,x4)                              \
 134                                        x1 =~ x1;       \
 135        x4  = x1;       x0 =~ x0;       x1 &= x2;       \
 136        x1 ^= x3;       x3 |= x4;       x4 ^= x2;       \
 137        x2 ^= x3;       x3 ^= x0;       x0 |= x1;       \
 138        x2 &= x0;       x0 ^= x4;       x4 ^= x3;       \
 139        x3 &= x0;       x4 ^= x1;                       \
 140        x2 ^= x4;       x3 ^= x1;       x4 |= x0;       \
 141        x4 ^= x1;
 142
 143#define SI0(x0,x1,x2,x3,x4)                             \
 144                        x4  = x3;       x1 ^= x0;       \
 145        x3 |= x1;       x4 ^= x1;       x0 =~ x0;       \
 146        x2 ^= x3;       x3 ^= x0;       x0 &= x1;       \
 147        x0 ^= x2;       x2 &= x3;       x3 ^= x4;       \
 148        x2 ^= x3;       x1 ^= x3;       x3 &= x0;       \
 149        x1 ^= x0;       x0 ^= x2;       x4 ^= x3;
 150
 151#define SI1(x0,x1,x2,x3,x4)                             \
 152        x1 ^= x3;       x4  = x0;                       \
 153        x0 ^= x2;       x2 =~ x2;       x4 |= x1;       \
 154        x4 ^= x3;       x3 &= x1;       x1 ^= x2;       \
 155        x2 &= x4;       x4 ^= x1;       x1 |= x3;       \
 156        x3 ^= x0;       x2 ^= x0;       x0 |= x4;       \
 157        x2 ^= x4;       x1 ^= x0;                       \
 158        x4 ^= x1;
 159
 160#define SI2(x0,x1,x2,x3,x4)                             \
 161        x2 ^= x1;       x4  = x3;       x3 =~ x3;       \
 162        x3 |= x2;       x2 ^= x4;       x4 ^= x0;       \
 163        x3 ^= x1;       x1 |= x2;       x2 ^= x0;       \
 164        x1 ^= x4;       x4 |= x3;       x2 ^= x3;       \
 165        x4 ^= x2;       x2 &= x1;                       \
 166        x2 ^= x3;       x3 ^= x4;       x4 ^= x0;
 167
 168#define SI3(x0,x1,x2,x3,x4)                             \
 169                                        x2 ^= x1;       \
 170        x4  = x1;       x1 &= x2;                       \
 171        x1 ^= x0;       x0 |= x4;       x4 ^= x3;       \
 172        x0 ^= x3;       x3 |= x1;       x1 ^= x2;       \
 173        x1 ^= x3;       x0 ^= x2;       x2 ^= x3;       \
 174        x3 &= x1;       x1 ^= x0;       x0 &= x2;       \
 175        x4 ^= x3;       x3 ^= x0;       x0 ^= x1;
 176
 177#define SI4(x0,x1,x2,x3,x4)                             \
 178        x2 ^= x3;       x4  = x0;       x0 &= x1;       \
 179        x0 ^= x2;       x2 |= x3;       x4 =~ x4;       \
 180        x1 ^= x0;       x0 ^= x2;       x2 &= x4;       \
 181        x2 ^= x0;       x0 |= x4;                       \
 182        x0 ^= x3;       x3 &= x2;                       \
 183        x4 ^= x3;       x3 ^= x1;       x1 &= x0;       \
 184        x4 ^= x1;       x0 ^= x3;
 185
 186#define SI5(x0,x1,x2,x3,x4)                             \
 187                        x4  = x1;       x1 |= x2;       \
 188        x2 ^= x4;       x1 ^= x3;       x3 &= x4;       \
 189        x2 ^= x3;       x3 |= x0;       x0 =~ x0;       \
 190        x3 ^= x2;       x2 |= x0;       x4 ^= x1;       \
 191        x2 ^= x4;       x4 &= x0;       x0 ^= x1;       \
 192        x1 ^= x3;       x0 &= x2;       x2 ^= x3;       \
 193        x0 ^= x2;       x2 ^= x4;       x4 ^= x3;
 194
 195#define SI6(x0,x1,x2,x3,x4)                             \
 196                        x0 ^= x2;                       \
 197        x4  = x0;       x0 &= x3;       x2 ^= x3;       \
 198        x0 ^= x2;       x3 ^= x1;       x2 |= x4;       \
 199        x2 ^= x3;       x3 &= x0;       x0 =~ x0;       \
 200        x3 ^= x1;       x1 &= x2;       x4 ^= x0;       \
 201        x3 ^= x4;       x4 ^= x2;       x0 ^= x1;       \
 202        x2 ^= x0;
 203
 204#define SI7(x0,x1,x2,x3,x4)                             \
 205        x4  = x3;       x3 &= x0;       x0 ^= x2;       \
 206        x2 |= x4;       x4 ^= x1;       x0 =~ x0;       \
 207        x1 |= x3;       x4 ^= x0;       x0 &= x2;       \
 208        x0 ^= x1;       x1 &= x2;       x3 ^= x2;       \
 209        x4 ^= x3;       x2 &= x3;       x3 |= x0;       \
 210        x1 ^= x4;       x3 ^= x4;       x4 &= x0;       \
 211        x4 ^= x2;
 212
 213struct serpent_ctx {
 214        u32 expkey[SERPENT_EXPKEY_WORDS];
 215};
 216
 217
 218static int serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
 219                          unsigned int keylen, u32 *flags)
 220{
 221        struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
 222        u32 *k = ctx->expkey;
 223        u8  *k8 = (u8 *)k;
 224        u32 r0,r1,r2,r3,r4;
 225        int i;
 226
 227        if ((keylen < SERPENT_MIN_KEY_SIZE)
 228                        || (keylen > SERPENT_MAX_KEY_SIZE))
 229        {
 230                *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
 231                return -EINVAL;
 232        }
 233
 234        /* Copy key, add padding */
 235
 236        for (i = 0; i < keylen; ++i)
 237                k8[i] = key[i];
 238        if (i < SERPENT_MAX_KEY_SIZE)
 239                k8[i++] = 1;
 240        while (i < SERPENT_MAX_KEY_SIZE)
 241                k8[i++] = 0;
 242
 243        /* Expand key using polynomial */
 244
 245        r0 = le32_to_cpu(k[3]);
 246        r1 = le32_to_cpu(k[4]);
 247        r2 = le32_to_cpu(k[5]);
 248        r3 = le32_to_cpu(k[6]);
 249        r4 = le32_to_cpu(k[7]);
 250
 251        keyiter(le32_to_cpu(k[0]),r0,r4,r2,0,0);
 252        keyiter(le32_to_cpu(k[1]),r1,r0,r3,1,1);
 253        keyiter(le32_to_cpu(k[2]),r2,r1,r4,2,2);
 254        keyiter(le32_to_cpu(k[3]),r3,r2,r0,3,3);
 255        keyiter(le32_to_cpu(k[4]),r4,r3,r1,4,4);
 256        keyiter(le32_to_cpu(k[5]),r0,r4,r2,5,5);
 257        keyiter(le32_to_cpu(k[6]),r1,r0,r3,6,6);
 258        keyiter(le32_to_cpu(k[7]),r2,r1,r4,7,7);
 259
 260        keyiter(k[  0],r3,r2,r0,  8,  8); keyiter(k[  1],r4,r3,r1,  9,  9);
 261        keyiter(k[  2],r0,r4,r2, 10, 10); keyiter(k[  3],r1,r0,r3, 11, 11);
 262        keyiter(k[  4],r2,r1,r4, 12, 12); keyiter(k[  5],r3,r2,r0, 13, 13);
 263        keyiter(k[  6],r4,r3,r1, 14, 14); keyiter(k[  7],r0,r4,r2, 15, 15);
 264        keyiter(k[  8],r1,r0,r3, 16, 16); keyiter(k[  9],r2,r1,r4, 17, 17);
 265        keyiter(k[ 10],r3,r2,r0, 18, 18); keyiter(k[ 11],r4,r3,r1, 19, 19);
 266        keyiter(k[ 12],r0,r4,r2, 20, 20); keyiter(k[ 13],r1,r0,r3, 21, 21);
 267        keyiter(k[ 14],r2,r1,r4, 22, 22); keyiter(k[ 15],r3,r2,r0, 23, 23);
 268        keyiter(k[ 16],r4,r3,r1, 24, 24); keyiter(k[ 17],r0,r4,r2, 25, 25);
 269        keyiter(k[ 18],r1,r0,r3, 26, 26); keyiter(k[ 19],r2,r1,r4, 27, 27);
 270        keyiter(k[ 20],r3,r2,r0, 28, 28); keyiter(k[ 21],r4,r3,r1, 29, 29);
 271        keyiter(k[ 22],r0,r4,r2, 30, 30); keyiter(k[ 23],r1,r0,r3, 31, 31);
 272
 273        k += 50;
 274
 275        keyiter(k[-26],r2,r1,r4, 32,-18); keyiter(k[-25],r3,r2,r0, 33,-17);
 276        keyiter(k[-24],r4,r3,r1, 34,-16); keyiter(k[-23],r0,r4,r2, 35,-15);
 277        keyiter(k[-22],r1,r0,r3, 36,-14); keyiter(k[-21],r2,r1,r4, 37,-13);
 278        keyiter(k[-20],r3,r2,r0, 38,-12); keyiter(k[-19],r4,r3,r1, 39,-11);
 279        keyiter(k[-18],r0,r4,r2, 40,-10); keyiter(k[-17],r1,r0,r3, 41, -9);
 280        keyiter(k[-16],r2,r1,r4, 42, -8); keyiter(k[-15],r3,r2,r0, 43, -7);
 281        keyiter(k[-14],r4,r3,r1, 44, -6); keyiter(k[-13],r0,r4,r2, 45, -5);
 282        keyiter(k[-12],r1,r0,r3, 46, -4); keyiter(k[-11],r2,r1,r4, 47, -3);
 283        keyiter(k[-10],r3,r2,r0, 48, -2); keyiter(k[ -9],r4,r3,r1, 49, -1);
 284        keyiter(k[ -8],r0,r4,r2, 50,  0); keyiter(k[ -7],r1,r0,r3, 51,  1);
 285        keyiter(k[ -6],r2,r1,r4, 52,  2); keyiter(k[ -5],r3,r2,r0, 53,  3);
 286        keyiter(k[ -4],r4,r3,r1, 54,  4); keyiter(k[ -3],r0,r4,r2, 55,  5);
 287        keyiter(k[ -2],r1,r0,r3, 56,  6); keyiter(k[ -1],r2,r1,r4, 57,  7);
 288        keyiter(k[  0],r3,r2,r0, 58,  8); keyiter(k[  1],r4,r3,r1, 59,  9);
 289        keyiter(k[  2],r0,r4,r2, 60, 10); keyiter(k[  3],r1,r0,r3, 61, 11);
 290        keyiter(k[  4],r2,r1,r4, 62, 12); keyiter(k[  5],r3,r2,r0, 63, 13);
 291        keyiter(k[  6],r4,r3,r1, 64, 14); keyiter(k[  7],r0,r4,r2, 65, 15);
 292        keyiter(k[  8],r1,r0,r3, 66, 16); keyiter(k[  9],r2,r1,r4, 67, 17);
 293        keyiter(k[ 10],r3,r2,r0, 68, 18); keyiter(k[ 11],r4,r3,r1, 69, 19);
 294        keyiter(k[ 12],r0,r4,r2, 70, 20); keyiter(k[ 13],r1,r0,r3, 71, 21);
 295        keyiter(k[ 14],r2,r1,r4, 72, 22); keyiter(k[ 15],r3,r2,r0, 73, 23);
 296        keyiter(k[ 16],r4,r3,r1, 74, 24); keyiter(k[ 17],r0,r4,r2, 75, 25);
 297        keyiter(k[ 18],r1,r0,r3, 76, 26); keyiter(k[ 19],r2,r1,r4, 77, 27);
 298        keyiter(k[ 20],r3,r2,r0, 78, 28); keyiter(k[ 21],r4,r3,r1, 79, 29);
 299        keyiter(k[ 22],r0,r4,r2, 80, 30); keyiter(k[ 23],r1,r0,r3, 81, 31);
 300
 301        k += 50;
 302
 303        keyiter(k[-26],r2,r1,r4, 82,-18); keyiter(k[-25],r3,r2,r0, 83,-17);
 304        keyiter(k[-24],r4,r3,r1, 84,-16); keyiter(k[-23],r0,r4,r2, 85,-15);
 305        keyiter(k[-22],r1,r0,r3, 86,-14); keyiter(k[-21],r2,r1,r4, 87,-13);
 306        keyiter(k[-20],r3,r2,r0, 88,-12); keyiter(k[-19],r4,r3,r1, 89,-11);
 307        keyiter(k[-18],r0,r4,r2, 90,-10); keyiter(k[-17],r1,r0,r3, 91, -9);
 308        keyiter(k[-16],r2,r1,r4, 92, -8); keyiter(k[-15],r3,r2,r0, 93, -7);
 309        keyiter(k[-14],r4,r3,r1, 94, -6); keyiter(k[-13],r0,r4,r2, 95, -5);
 310        keyiter(k[-12],r1,r0,r3, 96, -4); keyiter(k[-11],r2,r1,r4, 97, -3);
 311        keyiter(k[-10],r3,r2,r0, 98, -2); keyiter(k[ -9],r4,r3,r1, 99, -1);
 312        keyiter(k[ -8],r0,r4,r2,100,  0); keyiter(k[ -7],r1,r0,r3,101,  1);
 313        keyiter(k[ -6],r2,r1,r4,102,  2); keyiter(k[ -5],r3,r2,r0,103,  3);
 314        keyiter(k[ -4],r4,r3,r1,104,  4); keyiter(k[ -3],r0,r4,r2,105,  5);
 315        keyiter(k[ -2],r1,r0,r3,106,  6); keyiter(k[ -1],r2,r1,r4,107,  7);
 316        keyiter(k[  0],r3,r2,r0,108,  8); keyiter(k[  1],r4,r3,r1,109,  9);
 317        keyiter(k[  2],r0,r4,r2,110, 10); keyiter(k[  3],r1,r0,r3,111, 11);
 318        keyiter(k[  4],r2,r1,r4,112, 12); keyiter(k[  5],r3,r2,r0,113, 13);
 319        keyiter(k[  6],r4,r3,r1,114, 14); keyiter(k[  7],r0,r4,r2,115, 15);
 320        keyiter(k[  8],r1,r0,r3,116, 16); keyiter(k[  9],r2,r1,r4,117, 17);
 321        keyiter(k[ 10],r3,r2,r0,118, 18); keyiter(k[ 11],r4,r3,r1,119, 19);
 322        keyiter(k[ 12],r0,r4,r2,120, 20); keyiter(k[ 13],r1,r0,r3,121, 21);
 323        keyiter(k[ 14],r2,r1,r4,122, 22); keyiter(k[ 15],r3,r2,r0,123, 23);
 324        keyiter(k[ 16],r4,r3,r1,124, 24); keyiter(k[ 17],r0,r4,r2,125, 25);
 325        keyiter(k[ 18],r1,r0,r3,126, 26); keyiter(k[ 19],r2,r1,r4,127, 27);
 326        keyiter(k[ 20],r3,r2,r0,128, 28); keyiter(k[ 21],r4,r3,r1,129, 29);
 327        keyiter(k[ 22],r0,r4,r2,130, 30); keyiter(k[ 23],r1,r0,r3,131, 31);
 328
 329        /* Apply S-boxes */
 330
 331        S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 28); loadkeys(r1,r2,r4,r3, 24);
 332        S4(r1,r2,r4,r3,r0); storekeys(r2,r4,r3,r0, 24); loadkeys(r2,r4,r3,r0, 20);
 333        S5(r2,r4,r3,r0,r1); storekeys(r1,r2,r4,r0, 20); loadkeys(r1,r2,r4,r0, 16);
 334        S6(r1,r2,r4,r0,r3); storekeys(r4,r3,r2,r0, 16); loadkeys(r4,r3,r2,r0, 12);
 335        S7(r4,r3,r2,r0,r1); storekeys(r1,r2,r0,r4, 12); loadkeys(r1,r2,r0,r4,  8);
 336        S0(r1,r2,r0,r4,r3); storekeys(r0,r2,r4,r1,  8); loadkeys(r0,r2,r4,r1,  4);
 337        S1(r0,r2,r4,r1,r3); storekeys(r3,r4,r1,r0,  4); loadkeys(r3,r4,r1,r0,  0);
 338        S2(r3,r4,r1,r0,r2); storekeys(r2,r4,r3,r0,  0); loadkeys(r2,r4,r3,r0, -4);
 339        S3(r2,r4,r3,r0,r1); storekeys(r0,r1,r4,r2, -4); loadkeys(r0,r1,r4,r2, -8);
 340        S4(r0,r1,r4,r2,r3); storekeys(r1,r4,r2,r3, -8); loadkeys(r1,r4,r2,r3,-12);
 341        S5(r1,r4,r2,r3,r0); storekeys(r0,r1,r4,r3,-12); loadkeys(r0,r1,r4,r3,-16);
 342        S6(r0,r1,r4,r3,r2); storekeys(r4,r2,r1,r3,-16); loadkeys(r4,r2,r1,r3,-20);
 343        S7(r4,r2,r1,r3,r0); storekeys(r0,r1,r3,r4,-20); loadkeys(r0,r1,r3,r4,-24);
 344        S0(r0,r1,r3,r4,r2); storekeys(r3,r1,r4,r0,-24); loadkeys(r3,r1,r4,r0,-28);
 345        k -= 50;
 346        S1(r3,r1,r4,r0,r2); storekeys(r2,r4,r0,r3, 22); loadkeys(r2,r4,r0,r3, 18);
 347        S2(r2,r4,r0,r3,r1); storekeys(r1,r4,r2,r3, 18); loadkeys(r1,r4,r2,r3, 14);
 348        S3(r1,r4,r2,r3,r0); storekeys(r3,r0,r4,r1, 14); loadkeys(r3,r0,r4,r1, 10);
 349        S4(r3,r0,r4,r1,r2); storekeys(r0,r4,r1,r2, 10); loadkeys(r0,r4,r1,r2,  6);
 350        S5(r0,r4,r1,r2,r3); storekeys(r3,r0,r4,r2,  6); loadkeys(r3,r0,r4,r2,  2);
 351        S6(r3,r0,r4,r2,r1); storekeys(r4,r1,r0,r2,  2); loadkeys(r4,r1,r0,r2, -2);
 352        S7(r4,r1,r0,r2,r3); storekeys(r3,r0,r2,r4, -2); loadkeys(r3,r0,r2,r4, -6);
 353        S0(r3,r0,r2,r4,r1); storekeys(r2,r0,r4,r3, -6); loadkeys(r2,r0,r4,r3,-10);
 354        S1(r2,r0,r4,r3,r1); storekeys(r1,r4,r3,r2,-10); loadkeys(r1,r4,r3,r2,-14);
 355        S2(r1,r4,r3,r2,r0); storekeys(r0,r4,r1,r2,-14); loadkeys(r0,r4,r1,r2,-18);
 356        S3(r0,r4,r1,r2,r3); storekeys(r2,r3,r4,r0,-18); loadkeys(r2,r3,r4,r0,-22);
 357        k -= 50;
 358        S4(r2,r3,r4,r0,r1); storekeys(r3,r4,r0,r1, 28); loadkeys(r3,r4,r0,r1, 24);
 359        S5(r3,r4,r0,r1,r2); storekeys(r2,r3,r4,r1, 24); loadkeys(r2,r3,r4,r1, 20);
 360        S6(r2,r3,r4,r1,r0); storekeys(r4,r0,r3,r1, 20); loadkeys(r4,r0,r3,r1, 16);
 361        S7(r4,r0,r3,r1,r2); storekeys(r2,r3,r1,r4, 16); loadkeys(r2,r3,r1,r4, 12);
 362        S0(r2,r3,r1,r4,r0); storekeys(r1,r3,r4,r2, 12); loadkeys(r1,r3,r4,r2,  8);
 363        S1(r1,r3,r4,r2,r0); storekeys(r0,r4,r2,r1,  8); loadkeys(r0,r4,r2,r1,  4);
 364        S2(r0,r4,r2,r1,r3); storekeys(r3,r4,r0,r1,  4); loadkeys(r3,r4,r0,r1,  0);
 365        S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3,  0);
 366
 367        return 0;
 368}
 369
 370static void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 371{
 372        struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
 373        const u32
 374                *k = ctx->expkey,
 375                *s = (const u32 *)src;
 376        u32     *d = (u32 *)dst,
 377                r0, r1, r2, r3, r4;
 378
 379/*
 380 * Note: The conversions between u8* and u32* might cause trouble
 381 * on architectures with stricter alignment rules than x86
 382 */
 383
 384        r0 = le32_to_cpu(s[0]);
 385        r1 = le32_to_cpu(s[1]);
 386        r2 = le32_to_cpu(s[2]);
 387        r3 = le32_to_cpu(s[3]);
 388
 389                                 K(r0,r1,r2,r3,0);
 390        S0(r0,r1,r2,r3,r4);     LK(r2,r1,r3,r0,r4,1);
 391        S1(r2,r1,r3,r0,r4);     LK(r4,r3,r0,r2,r1,2);
 392        S2(r4,r3,r0,r2,r1);     LK(r1,r3,r4,r2,r0,3);
 393        S3(r1,r3,r4,r2,r0);     LK(r2,r0,r3,r1,r4,4);
 394        S4(r2,r0,r3,r1,r4);     LK(r0,r3,r1,r4,r2,5);
 395        S5(r0,r3,r1,r4,r2);     LK(r2,r0,r3,r4,r1,6);
 396        S6(r2,r0,r3,r4,r1);     LK(r3,r1,r0,r4,r2,7);
 397        S7(r3,r1,r0,r4,r2);     LK(r2,r0,r4,r3,r1,8);
 398        S0(r2,r0,r4,r3,r1);     LK(r4,r0,r3,r2,r1,9);
 399        S1(r4,r0,r3,r2,r1);     LK(r1,r3,r2,r4,r0,10);
 400        S2(r1,r3,r2,r4,r0);     LK(r0,r3,r1,r4,r2,11);
 401        S3(r0,r3,r1,r4,r2);     LK(r4,r2,r3,r0,r1,12);
 402        S4(r4,r2,r3,r0,r1);     LK(r2,r3,r0,r1,r4,13);
 403        S5(r2,r3,r0,r1,r4);     LK(r4,r2,r3,r1,r0,14);
 404        S6(r4,r2,r3,r1,r0);     LK(r3,r0,r2,r1,r4,15);
 405        S7(r3,r0,r2,r1,r4);     LK(r4,r2,r1,r3,r0,16);
 406        S0(r4,r2,r1,r3,r0);     LK(r1,r2,r3,r4,r0,17);
 407        S1(r1,r2,r3,r4,r0);     LK(r0,r3,r4,r1,r2,18);
 408        S2(r0,r3,r4,r1,r2);     LK(r2,r3,r0,r1,r4,19);
 409        S3(r2,r3,r0,r1,r4);     LK(r1,r4,r3,r2,r0,20);
 410        S4(r1,r4,r3,r2,r0);     LK(r4,r3,r2,r0,r1,21);
 411        S5(r4,r3,r2,r0,r1);     LK(r1,r4,r3,r0,r2,22);
 412        S6(r1,r4,r3,r0,r2);     LK(r3,r2,r4,r0,r1,23);
 413        S7(r3,r2,r4,r0,r1);     LK(r1,r4,r0,r3,r2,24);
 414        S0(r1,r4,r0,r3,r2);     LK(r0,r4,r3,r1,r2,25);
 415        S1(r0,r4,r3,r1,r2);     LK(r2,r3,r1,r0,r4,26);
 416        S2(r2,r3,r1,r0,r4);     LK(r4,r3,r2,r0,r1,27);
 417        S3(r4,r3,r2,r0,r1);     LK(r0,r1,r3,r4,r2,28);
 418        S4(r0,r1,r3,r4,r2);     LK(r1,r3,r4,r2,r0,29);
 419        S5(r1,r3,r4,r2,r0);     LK(r0,r1,r3,r2,r4,30);
 420        S6(r0,r1,r3,r2,r4);     LK(r3,r4,r1,r2,r0,31);
 421        S7(r3,r4,r1,r2,r0);      K(r0,r1,r2,r3,32);
 422
 423        d[0] = cpu_to_le32(r0);
 424        d[1] = cpu_to_le32(r1);
 425        d[2] = cpu_to_le32(r2);
 426        d[3] = cpu_to_le32(r3);
 427}
 428
 429static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 430{
 431        struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
 432        const u32
 433                *k = ((struct serpent_ctx *)ctx)->expkey,
 434                *s = (const u32 *)src;
 435        u32     *d = (u32 *)dst,
 436                r0, r1, r2, r3, r4;
 437
 438        r0 = le32_to_cpu(s[0]);
 439        r1 = le32_to_cpu(s[1]);
 440        r2 = le32_to_cpu(s[2]);
 441        r3 = le32_to_cpu(s[3]);
 442
 443                                K(r0,r1,r2,r3,32);
 444        SI7(r0,r1,r2,r3,r4);    KL(r1,r3,r0,r4,r2,31);
 445        SI6(r1,r3,r0,r4,r2);    KL(r0,r2,r4,r1,r3,30);
 446        SI5(r0,r2,r4,r1,r3);    KL(r2,r3,r0,r4,r1,29);
 447        SI4(r2,r3,r0,r4,r1);    KL(r2,r0,r1,r4,r3,28);
 448        SI3(r2,r0,r1,r4,r3);    KL(r1,r2,r3,r4,r0,27);
 449        SI2(r1,r2,r3,r4,r0);    KL(r2,r0,r4,r3,r1,26);
 450        SI1(r2,r0,r4,r3,r1);    KL(r1,r0,r4,r3,r2,25);
 451        SI0(r1,r0,r4,r3,r2);    KL(r4,r2,r0,r1,r3,24);
 452        SI7(r4,r2,r0,r1,r3);    KL(r2,r1,r4,r3,r0,23);
 453        SI6(r2,r1,r4,r3,r0);    KL(r4,r0,r3,r2,r1,22);
 454        SI5(r4,r0,r3,r2,r1);    KL(r0,r1,r4,r3,r2,21);
 455        SI4(r0,r1,r4,r3,r2);    KL(r0,r4,r2,r3,r1,20);
 456        SI3(r0,r4,r2,r3,r1);    KL(r2,r0,r1,r3,r4,19);
 457        SI2(r2,r0,r1,r3,r4);    KL(r0,r4,r3,r1,r2,18);
 458        SI1(r0,r4,r3,r1,r2);    KL(r2,r4,r3,r1,r0,17);
 459        SI0(r2,r4,r3,r1,r0);    KL(r3,r0,r4,r2,r1,16);
 460        SI7(r3,r0,r4,r2,r1);    KL(r0,r2,r3,r1,r4,15);
 461        SI6(r0,r2,r3,r1,r4);    KL(r3,r4,r1,r0,r2,14);
 462        SI5(r3,r4,r1,r0,r2);    KL(r4,r2,r3,r1,r0,13);
 463        SI4(r4,r2,r3,r1,r0);    KL(r4,r3,r0,r1,r2,12);
 464        SI3(r4,r3,r0,r1,r2);    KL(r0,r4,r2,r1,r3,11);
 465        SI2(r0,r4,r2,r1,r3);    KL(r4,r3,r1,r2,r0,10);
 466        SI1(r4,r3,r1,r2,r0);    KL(r0,r3,r1,r2,r4,9);
 467        SI0(r0,r3,r1,r2,r4);    KL(r1,r4,r3,r0,r2,8);
 468        SI7(r1,r4,r3,r0,r2);    KL(r4,r0,r1,r2,r3,7);
 469        SI6(r4,r0,r1,r2,r3);    KL(r1,r3,r2,r4,r0,6);
 470        SI5(r1,r3,r2,r4,r0);    KL(r3,r0,r1,r2,r4,5);
 471        SI4(r3,r0,r1,r2,r4);    KL(r3,r1,r4,r2,r0,4);
 472        SI3(r3,r1,r4,r2,r0);    KL(r4,r3,r0,r2,r1,3);
 473        SI2(r4,r3,r0,r2,r1);    KL(r3,r1,r2,r0,r4,2);
 474        SI1(r3,r1,r2,r0,r4);    KL(r4,r1,r2,r0,r3,1);
 475        SI0(r4,r1,r2,r0,r3);    K(r2,r3,r1,r4,0);
 476
 477        d[0] = cpu_to_le32(r2);
 478        d[1] = cpu_to_le32(r3);
 479        d[2] = cpu_to_le32(r1);
 480        d[3] = cpu_to_le32(r4);
 481}
 482
 483static struct crypto_alg serpent_alg = {
 484        .cra_name               =       "serpent",
 485        .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
 486        .cra_blocksize          =       SERPENT_BLOCK_SIZE,
 487        .cra_ctxsize            =       sizeof(struct serpent_ctx),
 488        .cra_alignmask          =       3,
 489        .cra_module             =       THIS_MODULE,
 490        .cra_list               =       LIST_HEAD_INIT(serpent_alg.cra_list),
 491        .cra_u                  =       { .cipher = {
 492        .cia_min_keysize        =       SERPENT_MIN_KEY_SIZE,
 493        .cia_max_keysize        =       SERPENT_MAX_KEY_SIZE,
 494        .cia_setkey             =       serpent_setkey,
 495        .cia_encrypt            =       serpent_encrypt,
 496        .cia_decrypt            =       serpent_decrypt } }
 497};
 498
 499static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key,
 500                          unsigned int keylen, u32 *flags)
 501{
 502        u8 rev_key[SERPENT_MAX_KEY_SIZE];
 503        int i;
 504
 505        if ((keylen < SERPENT_MIN_KEY_SIZE)
 506            || (keylen > SERPENT_MAX_KEY_SIZE)) {
 507                *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
 508                return -EINVAL;
 509        } 
 510
 511        for (i = 0; i < keylen; ++i)
 512                rev_key[keylen - i - 1] = key[i];
 513 
 514        return serpent_setkey(tfm, rev_key, keylen, flags);
 515}
 516
 517static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 518{
 519        const u32 * const s = (const u32 * const)src;
 520        u32 * const d = (u32 * const)dst;
 521
 522        u32 rs[4], rd[4];
 523
 524        rs[0] = swab32(s[3]);
 525        rs[1] = swab32(s[2]);
 526        rs[2] = swab32(s[1]);
 527        rs[3] = swab32(s[0]);
 528
 529        serpent_encrypt(tfm, (u8 *)rd, (u8 *)rs);
 530
 531        d[0] = swab32(rd[3]);
 532        d[1] = swab32(rd[2]);
 533        d[2] = swab32(rd[1]);
 534        d[3] = swab32(rd[0]);
 535}
 536
 537static void tnepres_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 538{
 539        const u32 * const s = (const u32 * const)src;
 540        u32 * const d = (u32 * const)dst;
 541
 542        u32 rs[4], rd[4];
 543
 544        rs[0] = swab32(s[3]);
 545        rs[1] = swab32(s[2]);
 546        rs[2] = swab32(s[1]);
 547        rs[3] = swab32(s[0]);
 548
 549        serpent_decrypt(tfm, (u8 *)rd, (u8 *)rs);
 550
 551        d[0] = swab32(rd[3]);
 552        d[1] = swab32(rd[2]);
 553        d[2] = swab32(rd[1]);
 554        d[3] = swab32(rd[0]);
 555}
 556
 557static struct crypto_alg tnepres_alg = {
 558        .cra_name               =       "tnepres",
 559        .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
 560        .cra_blocksize          =       SERPENT_BLOCK_SIZE,
 561        .cra_ctxsize            =       sizeof(struct serpent_ctx),
 562        .cra_alignmask          =       3,
 563        .cra_module             =       THIS_MODULE,
 564        .cra_list               =       LIST_HEAD_INIT(serpent_alg.cra_list),
 565        .cra_u                  =       { .cipher = {
 566        .cia_min_keysize        =       SERPENT_MIN_KEY_SIZE,
 567        .cia_max_keysize        =       SERPENT_MAX_KEY_SIZE,
 568        .cia_setkey             =       tnepres_setkey,
 569        .cia_encrypt            =       tnepres_encrypt,
 570        .cia_decrypt            =       tnepres_decrypt } }
 571};
 572
 573static int __init init(void)
 574{
 575        int ret = crypto_register_alg(&serpent_alg);
 576
 577        if (ret)
 578                return ret;
 579
 580        ret = crypto_register_alg(&tnepres_alg);
 581
 582        if (ret)
 583                crypto_unregister_alg(&serpent_alg);
 584
 585        return ret;
 586}
 587
 588static void __exit fini(void)
 589{
 590        crypto_unregister_alg(&tnepres_alg);
 591        crypto_unregister_alg(&serpent_alg);
 592}
 593
 594module_init(init);
 595module_exit(fini);
 596
 597MODULE_LICENSE("GPL");
 598MODULE_DESCRIPTION("Serpent and tnepres (kerneli compatible serpent reversed) Cipher Algorithm");
 599MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>");
 600MODULE_ALIAS("tnepres");
 601