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