linux/crypto/des_generic.c
<<
>>
Prefs
   1/*
   2 * Cryptographic API.
   3 *
   4 * DES & Triple DES EDE Cipher Algorithms.
   5 *
   6 * Copyright (c) 2005 Dag Arne Osvik <da@osvik.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
  15#include <asm/byteorder.h>
  16#include <linux/bitops.h>
  17#include <linux/init.h>
  18#include <linux/module.h>
  19#include <linux/errno.h>
  20#include <linux/crypto.h>
  21#include <linux/types.h>
  22
  23#include <crypto/des.h>
  24
  25#define ROL(x, r) ((x) = rol32((x), (r)))
  26#define ROR(x, r) ((x) = ror32((x), (r)))
  27
  28struct des_ctx {
  29        u32 expkey[DES_EXPKEY_WORDS];
  30};
  31
  32struct des3_ede_ctx {
  33        u32 expkey[DES3_EDE_EXPKEY_WORDS];
  34};
  35
  36/* Lookup tables for key expansion */
  37
  38static const u8 pc1[256] = {
  39        0x00, 0x00, 0x40, 0x04, 0x10, 0x10, 0x50, 0x14,
  40        0x04, 0x40, 0x44, 0x44, 0x14, 0x50, 0x54, 0x54,
  41        0x02, 0x02, 0x42, 0x06, 0x12, 0x12, 0x52, 0x16,
  42        0x06, 0x42, 0x46, 0x46, 0x16, 0x52, 0x56, 0x56,
  43        0x80, 0x08, 0xc0, 0x0c, 0x90, 0x18, 0xd0, 0x1c,
  44        0x84, 0x48, 0xc4, 0x4c, 0x94, 0x58, 0xd4, 0x5c,
  45        0x82, 0x0a, 0xc2, 0x0e, 0x92, 0x1a, 0xd2, 0x1e,
  46        0x86, 0x4a, 0xc6, 0x4e, 0x96, 0x5a, 0xd6, 0x5e,
  47        0x20, 0x20, 0x60, 0x24, 0x30, 0x30, 0x70, 0x34,
  48        0x24, 0x60, 0x64, 0x64, 0x34, 0x70, 0x74, 0x74,
  49        0x22, 0x22, 0x62, 0x26, 0x32, 0x32, 0x72, 0x36,
  50        0x26, 0x62, 0x66, 0x66, 0x36, 0x72, 0x76, 0x76,
  51        0xa0, 0x28, 0xe0, 0x2c, 0xb0, 0x38, 0xf0, 0x3c,
  52        0xa4, 0x68, 0xe4, 0x6c, 0xb4, 0x78, 0xf4, 0x7c,
  53        0xa2, 0x2a, 0xe2, 0x2e, 0xb2, 0x3a, 0xf2, 0x3e,
  54        0xa6, 0x6a, 0xe6, 0x6e, 0xb6, 0x7a, 0xf6, 0x7e,
  55        0x08, 0x80, 0x48, 0x84, 0x18, 0x90, 0x58, 0x94,
  56        0x0c, 0xc0, 0x4c, 0xc4, 0x1c, 0xd0, 0x5c, 0xd4,
  57        0x0a, 0x82, 0x4a, 0x86, 0x1a, 0x92, 0x5a, 0x96,
  58        0x0e, 0xc2, 0x4e, 0xc6, 0x1e, 0xd2, 0x5e, 0xd6,
  59        0x88, 0x88, 0xc8, 0x8c, 0x98, 0x98, 0xd8, 0x9c,
  60        0x8c, 0xc8, 0xcc, 0xcc, 0x9c, 0xd8, 0xdc, 0xdc,
  61        0x8a, 0x8a, 0xca, 0x8e, 0x9a, 0x9a, 0xda, 0x9e,
  62        0x8e, 0xca, 0xce, 0xce, 0x9e, 0xda, 0xde, 0xde,
  63        0x28, 0xa0, 0x68, 0xa4, 0x38, 0xb0, 0x78, 0xb4,
  64        0x2c, 0xe0, 0x6c, 0xe4, 0x3c, 0xf0, 0x7c, 0xf4,
  65        0x2a, 0xa2, 0x6a, 0xa6, 0x3a, 0xb2, 0x7a, 0xb6,
  66        0x2e, 0xe2, 0x6e, 0xe6, 0x3e, 0xf2, 0x7e, 0xf6,
  67        0xa8, 0xa8, 0xe8, 0xac, 0xb8, 0xb8, 0xf8, 0xbc,
  68        0xac, 0xe8, 0xec, 0xec, 0xbc, 0xf8, 0xfc, 0xfc,
  69        0xaa, 0xaa, 0xea, 0xae, 0xba, 0xba, 0xfa, 0xbe,
  70        0xae, 0xea, 0xee, 0xee, 0xbe, 0xfa, 0xfe, 0xfe
  71};
  72
  73static const u8 rs[256] = {
  74        0x00, 0x00, 0x80, 0x80, 0x02, 0x02, 0x82, 0x82,
  75        0x04, 0x04, 0x84, 0x84, 0x06, 0x06, 0x86, 0x86,
  76        0x08, 0x08, 0x88, 0x88, 0x0a, 0x0a, 0x8a, 0x8a,
  77        0x0c, 0x0c, 0x8c, 0x8c, 0x0e, 0x0e, 0x8e, 0x8e,
  78        0x10, 0x10, 0x90, 0x90, 0x12, 0x12, 0x92, 0x92,
  79        0x14, 0x14, 0x94, 0x94, 0x16, 0x16, 0x96, 0x96,
  80        0x18, 0x18, 0x98, 0x98, 0x1a, 0x1a, 0x9a, 0x9a,
  81        0x1c, 0x1c, 0x9c, 0x9c, 0x1e, 0x1e, 0x9e, 0x9e,
  82        0x20, 0x20, 0xa0, 0xa0, 0x22, 0x22, 0xa2, 0xa2,
  83        0x24, 0x24, 0xa4, 0xa4, 0x26, 0x26, 0xa6, 0xa6,
  84        0x28, 0x28, 0xa8, 0xa8, 0x2a, 0x2a, 0xaa, 0xaa,
  85        0x2c, 0x2c, 0xac, 0xac, 0x2e, 0x2e, 0xae, 0xae,
  86        0x30, 0x30, 0xb0, 0xb0, 0x32, 0x32, 0xb2, 0xb2,
  87        0x34, 0x34, 0xb4, 0xb4, 0x36, 0x36, 0xb6, 0xb6,
  88        0x38, 0x38, 0xb8, 0xb8, 0x3a, 0x3a, 0xba, 0xba,
  89        0x3c, 0x3c, 0xbc, 0xbc, 0x3e, 0x3e, 0xbe, 0xbe,
  90        0x40, 0x40, 0xc0, 0xc0, 0x42, 0x42, 0xc2, 0xc2,
  91        0x44, 0x44, 0xc4, 0xc4, 0x46, 0x46, 0xc6, 0xc6,
  92        0x48, 0x48, 0xc8, 0xc8, 0x4a, 0x4a, 0xca, 0xca,
  93        0x4c, 0x4c, 0xcc, 0xcc, 0x4e, 0x4e, 0xce, 0xce,
  94        0x50, 0x50, 0xd0, 0xd0, 0x52, 0x52, 0xd2, 0xd2,
  95        0x54, 0x54, 0xd4, 0xd4, 0x56, 0x56, 0xd6, 0xd6,
  96        0x58, 0x58, 0xd8, 0xd8, 0x5a, 0x5a, 0xda, 0xda,
  97        0x5c, 0x5c, 0xdc, 0xdc, 0x5e, 0x5e, 0xde, 0xde,
  98        0x60, 0x60, 0xe0, 0xe0, 0x62, 0x62, 0xe2, 0xe2,
  99        0x64, 0x64, 0xe4, 0xe4, 0x66, 0x66, 0xe6, 0xe6,
 100        0x68, 0x68, 0xe8, 0xe8, 0x6a, 0x6a, 0xea, 0xea,
 101        0x6c, 0x6c, 0xec, 0xec, 0x6e, 0x6e, 0xee, 0xee,
 102        0x70, 0x70, 0xf0, 0xf0, 0x72, 0x72, 0xf2, 0xf2,
 103        0x74, 0x74, 0xf4, 0xf4, 0x76, 0x76, 0xf6, 0xf6,
 104        0x78, 0x78, 0xf8, 0xf8, 0x7a, 0x7a, 0xfa, 0xfa,
 105        0x7c, 0x7c, 0xfc, 0xfc, 0x7e, 0x7e, 0xfe, 0xfe
 106};
 107
 108static const u32 pc2[1024] = {
 109        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 110        0x00040000, 0x00000000, 0x04000000, 0x00100000,
 111        0x00400000, 0x00000008, 0x00000800, 0x40000000,
 112        0x00440000, 0x00000008, 0x04000800, 0x40100000,
 113        0x00000400, 0x00000020, 0x08000000, 0x00000100,
 114        0x00040400, 0x00000020, 0x0c000000, 0x00100100,
 115        0x00400400, 0x00000028, 0x08000800, 0x40000100,
 116        0x00440400, 0x00000028, 0x0c000800, 0x40100100,
 117        0x80000000, 0x00000010, 0x00000000, 0x00800000,
 118        0x80040000, 0x00000010, 0x04000000, 0x00900000,
 119        0x80400000, 0x00000018, 0x00000800, 0x40800000,
 120        0x80440000, 0x00000018, 0x04000800, 0x40900000,
 121        0x80000400, 0x00000030, 0x08000000, 0x00800100,
 122        0x80040400, 0x00000030, 0x0c000000, 0x00900100,
 123        0x80400400, 0x00000038, 0x08000800, 0x40800100,
 124        0x80440400, 0x00000038, 0x0c000800, 0x40900100,
 125        0x10000000, 0x00000000, 0x00200000, 0x00001000,
 126        0x10040000, 0x00000000, 0x04200000, 0x00101000,
 127        0x10400000, 0x00000008, 0x00200800, 0x40001000,
 128        0x10440000, 0x00000008, 0x04200800, 0x40101000,
 129        0x10000400, 0x00000020, 0x08200000, 0x00001100,
 130        0x10040400, 0x00000020, 0x0c200000, 0x00101100,
 131        0x10400400, 0x00000028, 0x08200800, 0x40001100,
 132        0x10440400, 0x00000028, 0x0c200800, 0x40101100,
 133        0x90000000, 0x00000010, 0x00200000, 0x00801000,
 134        0x90040000, 0x00000010, 0x04200000, 0x00901000,
 135        0x90400000, 0x00000018, 0x00200800, 0x40801000,
 136        0x90440000, 0x00000018, 0x04200800, 0x40901000,
 137        0x90000400, 0x00000030, 0x08200000, 0x00801100,
 138        0x90040400, 0x00000030, 0x0c200000, 0x00901100,
 139        0x90400400, 0x00000038, 0x08200800, 0x40801100,
 140        0x90440400, 0x00000038, 0x0c200800, 0x40901100,
 141        0x00000200, 0x00080000, 0x00000000, 0x00000004,
 142        0x00040200, 0x00080000, 0x04000000, 0x00100004,
 143        0x00400200, 0x00080008, 0x00000800, 0x40000004,
 144        0x00440200, 0x00080008, 0x04000800, 0x40100004,
 145        0x00000600, 0x00080020, 0x08000000, 0x00000104,
 146        0x00040600, 0x00080020, 0x0c000000, 0x00100104,
 147        0x00400600, 0x00080028, 0x08000800, 0x40000104,
 148        0x00440600, 0x00080028, 0x0c000800, 0x40100104,
 149        0x80000200, 0x00080010, 0x00000000, 0x00800004,
 150        0x80040200, 0x00080010, 0x04000000, 0x00900004,
 151        0x80400200, 0x00080018, 0x00000800, 0x40800004,
 152        0x80440200, 0x00080018, 0x04000800, 0x40900004,
 153        0x80000600, 0x00080030, 0x08000000, 0x00800104,
 154        0x80040600, 0x00080030, 0x0c000000, 0x00900104,
 155        0x80400600, 0x00080038, 0x08000800, 0x40800104,
 156        0x80440600, 0x00080038, 0x0c000800, 0x40900104,
 157        0x10000200, 0x00080000, 0x00200000, 0x00001004,
 158        0x10040200, 0x00080000, 0x04200000, 0x00101004,
 159        0x10400200, 0x00080008, 0x00200800, 0x40001004,
 160        0x10440200, 0x00080008, 0x04200800, 0x40101004,
 161        0x10000600, 0x00080020, 0x08200000, 0x00001104,
 162        0x10040600, 0x00080020, 0x0c200000, 0x00101104,
 163        0x10400600, 0x00080028, 0x08200800, 0x40001104,
 164        0x10440600, 0x00080028, 0x0c200800, 0x40101104,
 165        0x90000200, 0x00080010, 0x00200000, 0x00801004,
 166        0x90040200, 0x00080010, 0x04200000, 0x00901004,
 167        0x90400200, 0x00080018, 0x00200800, 0x40801004,
 168        0x90440200, 0x00080018, 0x04200800, 0x40901004,
 169        0x90000600, 0x00080030, 0x08200000, 0x00801104,
 170        0x90040600, 0x00080030, 0x0c200000, 0x00901104,
 171        0x90400600, 0x00080038, 0x08200800, 0x40801104,
 172        0x90440600, 0x00080038, 0x0c200800, 0x40901104,
 173        0x00000002, 0x00002000, 0x20000000, 0x00000001,
 174        0x00040002, 0x00002000, 0x24000000, 0x00100001,
 175        0x00400002, 0x00002008, 0x20000800, 0x40000001,
 176        0x00440002, 0x00002008, 0x24000800, 0x40100001,
 177        0x00000402, 0x00002020, 0x28000000, 0x00000101,
 178        0x00040402, 0x00002020, 0x2c000000, 0x00100101,
 179        0x00400402, 0x00002028, 0x28000800, 0x40000101,
 180        0x00440402, 0x00002028, 0x2c000800, 0x40100101,
 181        0x80000002, 0x00002010, 0x20000000, 0x00800001,
 182        0x80040002, 0x00002010, 0x24000000, 0x00900001,
 183        0x80400002, 0x00002018, 0x20000800, 0x40800001,
 184        0x80440002, 0x00002018, 0x24000800, 0x40900001,
 185        0x80000402, 0x00002030, 0x28000000, 0x00800101,
 186        0x80040402, 0x00002030, 0x2c000000, 0x00900101,
 187        0x80400402, 0x00002038, 0x28000800, 0x40800101,
 188        0x80440402, 0x00002038, 0x2c000800, 0x40900101,
 189        0x10000002, 0x00002000, 0x20200000, 0x00001001,
 190        0x10040002, 0x00002000, 0x24200000, 0x00101001,
 191        0x10400002, 0x00002008, 0x20200800, 0x40001001,
 192        0x10440002, 0x00002008, 0x24200800, 0x40101001,
 193        0x10000402, 0x00002020, 0x28200000, 0x00001101,
 194        0x10040402, 0x00002020, 0x2c200000, 0x00101101,
 195        0x10400402, 0x00002028, 0x28200800, 0x40001101,
 196        0x10440402, 0x00002028, 0x2c200800, 0x40101101,
 197        0x90000002, 0x00002010, 0x20200000, 0x00801001,
 198        0x90040002, 0x00002010, 0x24200000, 0x00901001,
 199        0x90400002, 0x00002018, 0x20200800, 0x40801001,
 200        0x90440002, 0x00002018, 0x24200800, 0x40901001,
 201        0x90000402, 0x00002030, 0x28200000, 0x00801101,
 202        0x90040402, 0x00002030, 0x2c200000, 0x00901101,
 203        0x90400402, 0x00002038, 0x28200800, 0x40801101,
 204        0x90440402, 0x00002038, 0x2c200800, 0x40901101,
 205        0x00000202, 0x00082000, 0x20000000, 0x00000005,
 206        0x00040202, 0x00082000, 0x24000000, 0x00100005,
 207        0x00400202, 0x00082008, 0x20000800, 0x40000005,
 208        0x00440202, 0x00082008, 0x24000800, 0x40100005,
 209        0x00000602, 0x00082020, 0x28000000, 0x00000105,
 210        0x00040602, 0x00082020, 0x2c000000, 0x00100105,
 211        0x00400602, 0x00082028, 0x28000800, 0x40000105,
 212        0x00440602, 0x00082028, 0x2c000800, 0x40100105,
 213        0x80000202, 0x00082010, 0x20000000, 0x00800005,
 214        0x80040202, 0x00082010, 0x24000000, 0x00900005,
 215        0x80400202, 0x00082018, 0x20000800, 0x40800005,
 216        0x80440202, 0x00082018, 0x24000800, 0x40900005,
 217        0x80000602, 0x00082030, 0x28000000, 0x00800105,
 218        0x80040602, 0x00082030, 0x2c000000, 0x00900105,
 219        0x80400602, 0x00082038, 0x28000800, 0x40800105,
 220        0x80440602, 0x00082038, 0x2c000800, 0x40900105,
 221        0x10000202, 0x00082000, 0x20200000, 0x00001005,
 222        0x10040202, 0x00082000, 0x24200000, 0x00101005,
 223        0x10400202, 0x00082008, 0x20200800, 0x40001005,
 224        0x10440202, 0x00082008, 0x24200800, 0x40101005,
 225        0x10000602, 0x00082020, 0x28200000, 0x00001105,
 226        0x10040602, 0x00082020, 0x2c200000, 0x00101105,
 227        0x10400602, 0x00082028, 0x28200800, 0x40001105,
 228        0x10440602, 0x00082028, 0x2c200800, 0x40101105,
 229        0x90000202, 0x00082010, 0x20200000, 0x00801005,
 230        0x90040202, 0x00082010, 0x24200000, 0x00901005,
 231        0x90400202, 0x00082018, 0x20200800, 0x40801005,
 232        0x90440202, 0x00082018, 0x24200800, 0x40901005,
 233        0x90000602, 0x00082030, 0x28200000, 0x00801105,
 234        0x90040602, 0x00082030, 0x2c200000, 0x00901105,
 235        0x90400602, 0x00082038, 0x28200800, 0x40801105,
 236        0x90440602, 0x00082038, 0x2c200800, 0x40901105,
 237
 238        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 239        0x00000000, 0x00000008, 0x00080000, 0x10000000,
 240        0x02000000, 0x00000000, 0x00000080, 0x00001000,
 241        0x02000000, 0x00000008, 0x00080080, 0x10001000,
 242        0x00004000, 0x00000000, 0x00000040, 0x00040000,
 243        0x00004000, 0x00000008, 0x00080040, 0x10040000,
 244        0x02004000, 0x00000000, 0x000000c0, 0x00041000,
 245        0x02004000, 0x00000008, 0x000800c0, 0x10041000,
 246        0x00020000, 0x00008000, 0x08000000, 0x00200000,
 247        0x00020000, 0x00008008, 0x08080000, 0x10200000,
 248        0x02020000, 0x00008000, 0x08000080, 0x00201000,
 249        0x02020000, 0x00008008, 0x08080080, 0x10201000,
 250        0x00024000, 0x00008000, 0x08000040, 0x00240000,
 251        0x00024000, 0x00008008, 0x08080040, 0x10240000,
 252        0x02024000, 0x00008000, 0x080000c0, 0x00241000,
 253        0x02024000, 0x00008008, 0x080800c0, 0x10241000,
 254        0x00000000, 0x01000000, 0x00002000, 0x00000020,
 255        0x00000000, 0x01000008, 0x00082000, 0x10000020,
 256        0x02000000, 0x01000000, 0x00002080, 0x00001020,
 257        0x02000000, 0x01000008, 0x00082080, 0x10001020,
 258        0x00004000, 0x01000000, 0x00002040, 0x00040020,
 259        0x00004000, 0x01000008, 0x00082040, 0x10040020,
 260        0x02004000, 0x01000000, 0x000020c0, 0x00041020,
 261        0x02004000, 0x01000008, 0x000820c0, 0x10041020,
 262        0x00020000, 0x01008000, 0x08002000, 0x00200020,
 263        0x00020000, 0x01008008, 0x08082000, 0x10200020,
 264        0x02020000, 0x01008000, 0x08002080, 0x00201020,
 265        0x02020000, 0x01008008, 0x08082080, 0x10201020,
 266        0x00024000, 0x01008000, 0x08002040, 0x00240020,
 267        0x00024000, 0x01008008, 0x08082040, 0x10240020,
 268        0x02024000, 0x01008000, 0x080020c0, 0x00241020,
 269        0x02024000, 0x01008008, 0x080820c0, 0x10241020,
 270        0x00000400, 0x04000000, 0x00100000, 0x00000004,
 271        0x00000400, 0x04000008, 0x00180000, 0x10000004,
 272        0x02000400, 0x04000000, 0x00100080, 0x00001004,
 273        0x02000400, 0x04000008, 0x00180080, 0x10001004,
 274        0x00004400, 0x04000000, 0x00100040, 0x00040004,
 275        0x00004400, 0x04000008, 0x00180040, 0x10040004,
 276        0x02004400, 0x04000000, 0x001000c0, 0x00041004,
 277        0x02004400, 0x04000008, 0x001800c0, 0x10041004,
 278        0x00020400, 0x04008000, 0x08100000, 0x00200004,
 279        0x00020400, 0x04008008, 0x08180000, 0x10200004,
 280        0x02020400, 0x04008000, 0x08100080, 0x00201004,
 281        0x02020400, 0x04008008, 0x08180080, 0x10201004,
 282        0x00024400, 0x04008000, 0x08100040, 0x00240004,
 283        0x00024400, 0x04008008, 0x08180040, 0x10240004,
 284        0x02024400, 0x04008000, 0x081000c0, 0x00241004,
 285        0x02024400, 0x04008008, 0x081800c0, 0x10241004,
 286        0x00000400, 0x05000000, 0x00102000, 0x00000024,
 287        0x00000400, 0x05000008, 0x00182000, 0x10000024,
 288        0x02000400, 0x05000000, 0x00102080, 0x00001024,
 289        0x02000400, 0x05000008, 0x00182080, 0x10001024,
 290        0x00004400, 0x05000000, 0x00102040, 0x00040024,
 291        0x00004400, 0x05000008, 0x00182040, 0x10040024,
 292        0x02004400, 0x05000000, 0x001020c0, 0x00041024,
 293        0x02004400, 0x05000008, 0x001820c0, 0x10041024,
 294        0x00020400, 0x05008000, 0x08102000, 0x00200024,
 295        0x00020400, 0x05008008, 0x08182000, 0x10200024,
 296        0x02020400, 0x05008000, 0x08102080, 0x00201024,
 297        0x02020400, 0x05008008, 0x08182080, 0x10201024,
 298        0x00024400, 0x05008000, 0x08102040, 0x00240024,
 299        0x00024400, 0x05008008, 0x08182040, 0x10240024,
 300        0x02024400, 0x05008000, 0x081020c0, 0x00241024,
 301        0x02024400, 0x05008008, 0x081820c0, 0x10241024,
 302        0x00000800, 0x00010000, 0x20000000, 0x00000010,
 303        0x00000800, 0x00010008, 0x20080000, 0x10000010,
 304        0x02000800, 0x00010000, 0x20000080, 0x00001010,
 305        0x02000800, 0x00010008, 0x20080080, 0x10001010,
 306        0x00004800, 0x00010000, 0x20000040, 0x00040010,
 307        0x00004800, 0x00010008, 0x20080040, 0x10040010,
 308        0x02004800, 0x00010000, 0x200000c0, 0x00041010,
 309        0x02004800, 0x00010008, 0x200800c0, 0x10041010,
 310        0x00020800, 0x00018000, 0x28000000, 0x00200010,
 311        0x00020800, 0x00018008, 0x28080000, 0x10200010,
 312        0x02020800, 0x00018000, 0x28000080, 0x00201010,
 313        0x02020800, 0x00018008, 0x28080080, 0x10201010,
 314        0x00024800, 0x00018000, 0x28000040, 0x00240010,
 315        0x00024800, 0x00018008, 0x28080040, 0x10240010,
 316        0x02024800, 0x00018000, 0x280000c0, 0x00241010,
 317        0x02024800, 0x00018008, 0x280800c0, 0x10241010,
 318        0x00000800, 0x01010000, 0x20002000, 0x00000030,
 319        0x00000800, 0x01010008, 0x20082000, 0x10000030,
 320        0x02000800, 0x01010000, 0x20002080, 0x00001030,
 321        0x02000800, 0x01010008, 0x20082080, 0x10001030,
 322        0x00004800, 0x01010000, 0x20002040, 0x00040030,
 323        0x00004800, 0x01010008, 0x20082040, 0x10040030,
 324        0x02004800, 0x01010000, 0x200020c0, 0x00041030,
 325        0x02004800, 0x01010008, 0x200820c0, 0x10041030,
 326        0x00020800, 0x01018000, 0x28002000, 0x00200030,
 327        0x00020800, 0x01018008, 0x28082000, 0x10200030,
 328        0x02020800, 0x01018000, 0x28002080, 0x00201030,
 329        0x02020800, 0x01018008, 0x28082080, 0x10201030,
 330        0x00024800, 0x01018000, 0x28002040, 0x00240030,
 331        0x00024800, 0x01018008, 0x28082040, 0x10240030,
 332        0x02024800, 0x01018000, 0x280020c0, 0x00241030,
 333        0x02024800, 0x01018008, 0x280820c0, 0x10241030,
 334        0x00000c00, 0x04010000, 0x20100000, 0x00000014,
 335        0x00000c00, 0x04010008, 0x20180000, 0x10000014,
 336        0x02000c00, 0x04010000, 0x20100080, 0x00001014,
 337        0x02000c00, 0x04010008, 0x20180080, 0x10001014,
 338        0x00004c00, 0x04010000, 0x20100040, 0x00040014,
 339        0x00004c00, 0x04010008, 0x20180040, 0x10040014,
 340        0x02004c00, 0x04010000, 0x201000c0, 0x00041014,
 341        0x02004c00, 0x04010008, 0x201800c0, 0x10041014,
 342        0x00020c00, 0x04018000, 0x28100000, 0x00200014,
 343        0x00020c00, 0x04018008, 0x28180000, 0x10200014,
 344        0x02020c00, 0x04018000, 0x28100080, 0x00201014,
 345        0x02020c00, 0x04018008, 0x28180080, 0x10201014,
 346        0x00024c00, 0x04018000, 0x28100040, 0x00240014,
 347        0x00024c00, 0x04018008, 0x28180040, 0x10240014,
 348        0x02024c00, 0x04018000, 0x281000c0, 0x00241014,
 349        0x02024c00, 0x04018008, 0x281800c0, 0x10241014,
 350        0x00000c00, 0x05010000, 0x20102000, 0x00000034,
 351        0x00000c00, 0x05010008, 0x20182000, 0x10000034,
 352        0x02000c00, 0x05010000, 0x20102080, 0x00001034,
 353        0x02000c00, 0x05010008, 0x20182080, 0x10001034,
 354        0x00004c00, 0x05010000, 0x20102040, 0x00040034,
 355        0x00004c00, 0x05010008, 0x20182040, 0x10040034,
 356        0x02004c00, 0x05010000, 0x201020c0, 0x00041034,
 357        0x02004c00, 0x05010008, 0x201820c0, 0x10041034,
 358        0x00020c00, 0x05018000, 0x28102000, 0x00200034,
 359        0x00020c00, 0x05018008, 0x28182000, 0x10200034,
 360        0x02020c00, 0x05018000, 0x28102080, 0x00201034,
 361        0x02020c00, 0x05018008, 0x28182080, 0x10201034,
 362        0x00024c00, 0x05018000, 0x28102040, 0x00240034,
 363        0x00024c00, 0x05018008, 0x28182040, 0x10240034,
 364        0x02024c00, 0x05018000, 0x281020c0, 0x00241034,
 365        0x02024c00, 0x05018008, 0x281820c0, 0x10241034
 366};
 367
 368/* S-box lookup tables */
 369
 370static const u32 S1[64] = {
 371        0x01010400, 0x00000000, 0x00010000, 0x01010404,
 372        0x01010004, 0x00010404, 0x00000004, 0x00010000,
 373        0x00000400, 0x01010400, 0x01010404, 0x00000400,
 374        0x01000404, 0x01010004, 0x01000000, 0x00000004,
 375        0x00000404, 0x01000400, 0x01000400, 0x00010400,
 376        0x00010400, 0x01010000, 0x01010000, 0x01000404,
 377        0x00010004, 0x01000004, 0x01000004, 0x00010004,
 378        0x00000000, 0x00000404, 0x00010404, 0x01000000,
 379        0x00010000, 0x01010404, 0x00000004, 0x01010000,
 380        0x01010400, 0x01000000, 0x01000000, 0x00000400,
 381        0x01010004, 0x00010000, 0x00010400, 0x01000004,
 382        0x00000400, 0x00000004, 0x01000404, 0x00010404,
 383        0x01010404, 0x00010004, 0x01010000, 0x01000404,
 384        0x01000004, 0x00000404, 0x00010404, 0x01010400,
 385        0x00000404, 0x01000400, 0x01000400, 0x00000000,
 386        0x00010004, 0x00010400, 0x00000000, 0x01010004
 387};
 388
 389static const u32 S2[64] = {
 390        0x80108020, 0x80008000, 0x00008000, 0x00108020,
 391        0x00100000, 0x00000020, 0x80100020, 0x80008020,
 392        0x80000020, 0x80108020, 0x80108000, 0x80000000,
 393        0x80008000, 0x00100000, 0x00000020, 0x80100020,
 394        0x00108000, 0x00100020, 0x80008020, 0x00000000,
 395        0x80000000, 0x00008000, 0x00108020, 0x80100000,
 396        0x00100020, 0x80000020, 0x00000000, 0x00108000,
 397        0x00008020, 0x80108000, 0x80100000, 0x00008020,
 398        0x00000000, 0x00108020, 0x80100020, 0x00100000,
 399        0x80008020, 0x80100000, 0x80108000, 0x00008000,
 400        0x80100000, 0x80008000, 0x00000020, 0x80108020,
 401        0x00108020, 0x00000020, 0x00008000, 0x80000000,
 402        0x00008020, 0x80108000, 0x00100000, 0x80000020,
 403        0x00100020, 0x80008020, 0x80000020, 0x00100020,
 404        0x00108000, 0x00000000, 0x80008000, 0x00008020,
 405        0x80000000, 0x80100020, 0x80108020, 0x00108000
 406};
 407
 408static const u32 S3[64] = {
 409        0x00000208, 0x08020200, 0x00000000, 0x08020008,
 410        0x08000200, 0x00000000, 0x00020208, 0x08000200,
 411        0x00020008, 0x08000008, 0x08000008, 0x00020000,
 412        0x08020208, 0x00020008, 0x08020000, 0x00000208,
 413        0x08000000, 0x00000008, 0x08020200, 0x00000200,
 414        0x00020200, 0x08020000, 0x08020008, 0x00020208,
 415        0x08000208, 0x00020200, 0x00020000, 0x08000208,
 416        0x00000008, 0x08020208, 0x00000200, 0x08000000,
 417        0x08020200, 0x08000000, 0x00020008, 0x00000208,
 418        0x00020000, 0x08020200, 0x08000200, 0x00000000,
 419        0x00000200, 0x00020008, 0x08020208, 0x08000200,
 420        0x08000008, 0x00000200, 0x00000000, 0x08020008,
 421        0x08000208, 0x00020000, 0x08000000, 0x08020208,
 422        0x00000008, 0x00020208, 0x00020200, 0x08000008,
 423        0x08020000, 0x08000208, 0x00000208, 0x08020000,
 424        0x00020208, 0x00000008, 0x08020008, 0x00020200
 425};
 426
 427static const u32 S4[64] = {
 428        0x00802001, 0x00002081, 0x00002081, 0x00000080,
 429        0x00802080, 0x00800081, 0x00800001, 0x00002001,
 430        0x00000000, 0x00802000, 0x00802000, 0x00802081,
 431        0x00000081, 0x00000000, 0x00800080, 0x00800001,
 432        0x00000001, 0x00002000, 0x00800000, 0x00802001,
 433        0x00000080, 0x00800000, 0x00002001, 0x00002080,
 434        0x00800081, 0x00000001, 0x00002080, 0x00800080,
 435        0x00002000, 0x00802080, 0x00802081, 0x00000081,
 436        0x00800080, 0x00800001, 0x00802000, 0x00802081,
 437        0x00000081, 0x00000000, 0x00000000, 0x00802000,
 438        0x00002080, 0x00800080, 0x00800081, 0x00000001,
 439        0x00802001, 0x00002081, 0x00002081, 0x00000080,
 440        0x00802081, 0x00000081, 0x00000001, 0x00002000,
 441        0x00800001, 0x00002001, 0x00802080, 0x00800081,
 442        0x00002001, 0x00002080, 0x00800000, 0x00802001,
 443        0x00000080, 0x00800000, 0x00002000, 0x00802080
 444};
 445
 446static const u32 S5[64] = {
 447        0x00000100, 0x02080100, 0x02080000, 0x42000100,
 448        0x00080000, 0x00000100, 0x40000000, 0x02080000,
 449        0x40080100, 0x00080000, 0x02000100, 0x40080100,
 450        0x42000100, 0x42080000, 0x00080100, 0x40000000,
 451        0x02000000, 0x40080000, 0x40080000, 0x00000000,
 452        0x40000100, 0x42080100, 0x42080100, 0x02000100,
 453        0x42080000, 0x40000100, 0x00000000, 0x42000000,
 454        0x02080100, 0x02000000, 0x42000000, 0x00080100,
 455        0x00080000, 0x42000100, 0x00000100, 0x02000000,
 456        0x40000000, 0x02080000, 0x42000100, 0x40080100,
 457        0x02000100, 0x40000000, 0x42080000, 0x02080100,
 458        0x40080100, 0x00000100, 0x02000000, 0x42080000,
 459        0x42080100, 0x00080100, 0x42000000, 0x42080100,
 460        0x02080000, 0x00000000, 0x40080000, 0x42000000,
 461        0x00080100, 0x02000100, 0x40000100, 0x00080000,
 462        0x00000000, 0x40080000, 0x02080100, 0x40000100
 463};
 464
 465static const u32 S6[64] = {
 466        0x20000010, 0x20400000, 0x00004000, 0x20404010,
 467        0x20400000, 0x00000010, 0x20404010, 0x00400000,
 468        0x20004000, 0x00404010, 0x00400000, 0x20000010,
 469        0x00400010, 0x20004000, 0x20000000, 0x00004010,
 470        0x00000000, 0x00400010, 0x20004010, 0x00004000,
 471        0x00404000, 0x20004010, 0x00000010, 0x20400010,
 472        0x20400010, 0x00000000, 0x00404010, 0x20404000,
 473        0x00004010, 0x00404000, 0x20404000, 0x20000000,
 474        0x20004000, 0x00000010, 0x20400010, 0x00404000,
 475        0x20404010, 0x00400000, 0x00004010, 0x20000010,
 476        0x00400000, 0x20004000, 0x20000000, 0x00004010,
 477        0x20000010, 0x20404010, 0x00404000, 0x20400000,
 478        0x00404010, 0x20404000, 0x00000000, 0x20400010,
 479        0x00000010, 0x00004000, 0x20400000, 0x00404010,
 480        0x00004000, 0x00400010, 0x20004010, 0x00000000,
 481        0x20404000, 0x20000000, 0x00400010, 0x20004010
 482};
 483
 484static const u32 S7[64] = {
 485        0x00200000, 0x04200002, 0x04000802, 0x00000000,
 486        0x00000800, 0x04000802, 0x00200802, 0x04200800,
 487        0x04200802, 0x00200000, 0x00000000, 0x04000002,
 488        0x00000002, 0x04000000, 0x04200002, 0x00000802,
 489        0x04000800, 0x00200802, 0x00200002, 0x04000800,
 490        0x04000002, 0x04200000, 0x04200800, 0x00200002,
 491        0x04200000, 0x00000800, 0x00000802, 0x04200802,
 492        0x00200800, 0x00000002, 0x04000000, 0x00200800,
 493        0x04000000, 0x00200800, 0x00200000, 0x04000802,
 494        0x04000802, 0x04200002, 0x04200002, 0x00000002,
 495        0x00200002, 0x04000000, 0x04000800, 0x00200000,
 496        0x04200800, 0x00000802, 0x00200802, 0x04200800,
 497        0x00000802, 0x04000002, 0x04200802, 0x04200000,
 498        0x00200800, 0x00000000, 0x00000002, 0x04200802,
 499        0x00000000, 0x00200802, 0x04200000, 0x00000800,
 500        0x04000002, 0x04000800, 0x00000800, 0x00200002
 501};
 502
 503static const u32 S8[64] = {
 504        0x10001040, 0x00001000, 0x00040000, 0x10041040,
 505        0x10000000, 0x10001040, 0x00000040, 0x10000000,
 506        0x00040040, 0x10040000, 0x10041040, 0x00041000,
 507        0x10041000, 0x00041040, 0x00001000, 0x00000040,
 508        0x10040000, 0x10000040, 0x10001000, 0x00001040,
 509        0x00041000, 0x00040040, 0x10040040, 0x10041000,
 510        0x00001040, 0x00000000, 0x00000000, 0x10040040,
 511        0x10000040, 0x10001000, 0x00041040, 0x00040000,
 512        0x00041040, 0x00040000, 0x10041000, 0x00001000,
 513        0x00000040, 0x10040040, 0x00001000, 0x00041040,
 514        0x10001000, 0x00000040, 0x10000040, 0x10040000,
 515        0x10040040, 0x10000000, 0x00040000, 0x10001040,
 516        0x00000000, 0x10041040, 0x00040040, 0x10000040,
 517        0x10040000, 0x10001000, 0x10001040, 0x00000000,
 518        0x10041040, 0x00041000, 0x00041000, 0x00001040,
 519        0x00001040, 0x00040040, 0x10000000, 0x10041000
 520};
 521
 522/* Encryption components: IP, FP, and round function */
 523
 524#define IP(L, R, T)             \
 525        ROL(R, 4);              \
 526        T  = L;                 \
 527        L ^= R;                 \
 528        L &= 0xf0f0f0f0;        \
 529        R ^= L;                 \
 530        L ^= T;                 \
 531        ROL(R, 12);             \
 532        T  = L;                 \
 533        L ^= R;                 \
 534        L &= 0xffff0000;        \
 535        R ^= L;                 \
 536        L ^= T;                 \
 537        ROR(R, 14);             \
 538        T  = L;                 \
 539        L ^= R;                 \
 540        L &= 0xcccccccc;        \
 541        R ^= L;                 \
 542        L ^= T;                 \
 543        ROL(R, 6);              \
 544        T  = L;                 \
 545        L ^= R;                 \
 546        L &= 0xff00ff00;        \
 547        R ^= L;                 \
 548        L ^= T;                 \
 549        ROR(R, 7);              \
 550        T  = L;                 \
 551        L ^= R;                 \
 552        L &= 0xaaaaaaaa;        \
 553        R ^= L;                 \
 554        L ^= T;                 \
 555        ROL(L, 1);
 556
 557#define FP(L, R, T)             \
 558        ROR(L, 1);              \
 559        T  = L;                 \
 560        L ^= R;                 \
 561        L &= 0xaaaaaaaa;        \
 562        R ^= L;                 \
 563        L ^= T;                 \
 564        ROL(R, 7);              \
 565        T  = L;                 \
 566        L ^= R;                 \
 567        L &= 0xff00ff00;        \
 568        R ^= L;                 \
 569        L ^= T;                 \
 570        ROR(R, 6);              \
 571        T  = L;                 \
 572        L ^= R;                 \
 573        L &= 0xcccccccc;        \
 574        R ^= L;                 \
 575        L ^= T;                 \
 576        ROL(R, 14);             \
 577        T  = L;                 \
 578        L ^= R;                 \
 579        L &= 0xffff0000;        \
 580        R ^= L;                 \
 581        L ^= T;                 \
 582        ROR(R, 12);             \
 583        T  = L;                 \
 584        L ^= R;                 \
 585        L &= 0xf0f0f0f0;        \
 586        R ^= L;                 \
 587        L ^= T;                 \
 588        ROR(R, 4);
 589
 590#define ROUND(L, R, A, B, K, d)                                 \
 591        B = K[0];                       A = K[1];       K += d; \
 592        B ^= R;                         A ^= R;                 \
 593        B &= 0x3f3f3f3f;                ROR(A, 4);              \
 594        L ^= S8[0xff & B];              A &= 0x3f3f3f3f;        \
 595        L ^= S6[0xff & (B >> 8)];       B >>= 16;               \
 596        L ^= S7[0xff & A];                                      \
 597        L ^= S5[0xff & (A >> 8)];       A >>= 16;               \
 598        L ^= S4[0xff & B];                                      \
 599        L ^= S2[0xff & (B >> 8)];                               \
 600        L ^= S3[0xff & A];                                      \
 601        L ^= S1[0xff & (A >> 8)];
 602
 603/*
 604 * PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved
 605 * tables of 128 elements.  One set is for C_i and the other for D_i, while
 606 * the 4 interleaved tables correspond to four 7-bit subsets of C_i or D_i.
 607 *
 608 * After PC1 each of the variables a,b,c,d contains a 7 bit subset of C_i
 609 * or D_i in bits 7-1 (bit 0 being the least significant).
 610 */
 611
 612#define T1(x) pt[2 * (x) + 0]
 613#define T2(x) pt[2 * (x) + 1]
 614#define T3(x) pt[2 * (x) + 2]
 615#define T4(x) pt[2 * (x) + 3]
 616
 617#define DES_PC2(a, b, c, d) (T4(d) | T3(c) | T2(b) | T1(a))
 618
 619/*
 620 * Encryption key expansion
 621 *
 622 * RFC2451: Weak key checks SHOULD be performed.
 623 *
 624 * FIPS 74:
 625 *
 626 *   Keys having duals are keys which produce all zeros, all ones, or
 627 *   alternating zero-one patterns in the C and D registers after Permuted
 628 *   Choice 1 has operated on the key.
 629 *
 630 */
 631unsigned long des_ekey(u32 *pe, const u8 *k)
 632{
 633        /* K&R: long is at least 32 bits */
 634        unsigned long a, b, c, d, w;
 635        const u32 *pt = pc2;
 636
 637        d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
 638        c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
 639        b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
 640        a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
 641
 642        pe[15 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d];
 643        pe[14 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 644        pe[13 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 645        pe[12 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 646        pe[11 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 647        pe[10 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 648        pe[ 9 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 649        pe[ 8 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c];
 650        pe[ 7 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 651        pe[ 6 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 652        pe[ 5 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 653        pe[ 4 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 654        pe[ 3 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 655        pe[ 2 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 656        pe[ 1 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b];
 657        pe[ 0 * 2 + 0] = DES_PC2(b, c, d, a);
 658
 659        /* Check if first half is weak */
 660        w  = (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
 661
 662        /* Skip to next table set */
 663        pt += 512;
 664
 665        d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
 666        c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
 667        b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
 668        a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
 669
 670        /* Check if second half is weak */
 671        w |= (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
 672
 673        pe[15 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d];
 674        pe[14 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 675        pe[13 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 676        pe[12 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 677        pe[11 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 678        pe[10 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 679        pe[ 9 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 680        pe[ 8 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c];
 681        pe[ 7 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 682        pe[ 6 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 683        pe[ 5 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 684        pe[ 4 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 685        pe[ 3 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 686        pe[ 2 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 687        pe[ 1 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b];
 688        pe[ 0 * 2 + 1] = DES_PC2(b, c, d, a);
 689
 690        /* Fixup: 2413 5768 -> 1357 2468 */
 691        for (d = 0; d < 16; ++d) {
 692                a = pe[2 * d];
 693                b = pe[2 * d + 1];
 694                c = a ^ b;
 695                c &= 0xffff0000;
 696                a ^= c;
 697                b ^= c;
 698                ROL(b, 18);
 699                pe[2 * d] = a;
 700                pe[2 * d + 1] = b;
 701        }
 702
 703        /* Zero if weak key */
 704        return w;
 705}
 706EXPORT_SYMBOL_GPL(des_ekey);
 707
 708/*
 709 * Decryption key expansion
 710 *
 711 * No weak key checking is performed, as this is only used by triple DES
 712 *
 713 */
 714static void dkey(u32 *pe, const u8 *k)
 715{
 716        /* K&R: long is at least 32 bits */
 717        unsigned long a, b, c, d;
 718        const u32 *pt = pc2;
 719
 720        d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
 721        c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
 722        b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
 723        a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
 724
 725        pe[ 0 * 2] = DES_PC2(a, b, c, d); d = rs[d];
 726        pe[ 1 * 2] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 727        pe[ 2 * 2] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 728        pe[ 3 * 2] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 729        pe[ 4 * 2] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 730        pe[ 5 * 2] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 731        pe[ 6 * 2] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 732        pe[ 7 * 2] = DES_PC2(d, a, b, c); c = rs[c];
 733        pe[ 8 * 2] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 734        pe[ 9 * 2] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 735        pe[10 * 2] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 736        pe[11 * 2] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 737        pe[12 * 2] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 738        pe[13 * 2] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 739        pe[14 * 2] = DES_PC2(c, d, a, b); b = rs[b];
 740        pe[15 * 2] = DES_PC2(b, c, d, a);
 741
 742        /* Skip to next table set */
 743        pt += 512;
 744
 745        d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
 746        c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
 747        b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
 748        a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
 749
 750        pe[ 0 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d];
 751        pe[ 1 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 752        pe[ 2 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 753        pe[ 3 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 754        pe[ 4 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 755        pe[ 5 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
 756        pe[ 6 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
 757        pe[ 7 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c];
 758        pe[ 8 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 759        pe[ 9 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 760        pe[10 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 761        pe[11 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 762        pe[12 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
 763        pe[13 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
 764        pe[14 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b];
 765        pe[15 * 2 + 1] = DES_PC2(b, c, d, a);
 766
 767        /* Fixup: 2413 5768 -> 1357 2468 */
 768        for (d = 0; d < 16; ++d) {
 769                a = pe[2 * d];
 770                b = pe[2 * d + 1];
 771                c = a ^ b;
 772                c &= 0xffff0000;
 773                a ^= c;
 774                b ^= c;
 775                ROL(b, 18);
 776                pe[2 * d] = a;
 777                pe[2 * d + 1] = b;
 778        }
 779}
 780
 781static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
 782                      unsigned int keylen)
 783{
 784        struct des_ctx *dctx = crypto_tfm_ctx(tfm);
 785        u32 *flags = &tfm->crt_flags;
 786        u32 tmp[DES_EXPKEY_WORDS];
 787        int ret;
 788
 789        /* Expand to tmp */
 790        ret = des_ekey(tmp, key);
 791
 792        if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
 793                *flags |= CRYPTO_TFM_RES_WEAK_KEY;
 794                return -EINVAL;
 795        }
 796
 797        /* Copy to output */
 798        memcpy(dctx->expkey, tmp, sizeof(dctx->expkey));
 799
 800        return 0;
 801}
 802
 803static void des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 804{
 805        struct des_ctx *ctx = crypto_tfm_ctx(tfm);
 806        const u32 *K = ctx->expkey;
 807        const __le32 *s = (const __le32 *)src;
 808        __le32 *d = (__le32 *)dst;
 809        u32 L, R, A, B;
 810        int i;
 811
 812        L = le32_to_cpu(s[0]);
 813        R = le32_to_cpu(s[1]);
 814
 815        IP(L, R, A);
 816        for (i = 0; i < 8; i++) {
 817                ROUND(L, R, A, B, K, 2);
 818                ROUND(R, L, A, B, K, 2);
 819        }
 820        FP(R, L, A);
 821
 822        d[0] = cpu_to_le32(R);
 823        d[1] = cpu_to_le32(L);
 824}
 825
 826static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 827{
 828        struct des_ctx *ctx = crypto_tfm_ctx(tfm);
 829        const u32 *K = ctx->expkey + DES_EXPKEY_WORDS - 2;
 830        const __le32 *s = (const __le32 *)src;
 831        __le32 *d = (__le32 *)dst;
 832        u32 L, R, A, B;
 833        int i;
 834
 835        L = le32_to_cpu(s[0]);
 836        R = le32_to_cpu(s[1]);
 837
 838        IP(L, R, A);
 839        for (i = 0; i < 8; i++) {
 840                ROUND(L, R, A, B, K, -2);
 841                ROUND(R, L, A, B, K, -2);
 842        }
 843        FP(R, L, A);
 844
 845        d[0] = cpu_to_le32(R);
 846        d[1] = cpu_to_le32(L);
 847}
 848
 849/*
 850 * RFC2451:
 851 *
 852 *   For DES-EDE3, there is no known need to reject weak or
 853 *   complementation keys.  Any weakness is obviated by the use of
 854 *   multiple keys.
 855 *
 856 *   However, if the first two or last two independent 64-bit keys are
 857 *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
 858 *   same as DES.  Implementers MUST reject keys that exhibit this
 859 *   property.
 860 *
 861 */
 862static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
 863                           unsigned int keylen)
 864{
 865        const u32 *K = (const u32 *)key;
 866        struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
 867        u32 *expkey = dctx->expkey;
 868        u32 *flags = &tfm->crt_flags;
 869
 870        if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
 871                     !((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
 872                     (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
 873                *flags |= CRYPTO_TFM_RES_WEAK_KEY;
 874                return -EINVAL;
 875        }
 876
 877        des_ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
 878        dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
 879        des_ekey(expkey, key);
 880
 881        return 0;
 882}
 883
 884static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 885{
 886        struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
 887        const u32 *K = dctx->expkey;
 888        const __le32 *s = (const __le32 *)src;
 889        __le32 *d = (__le32 *)dst;
 890        u32 L, R, A, B;
 891        int i;
 892
 893        L = le32_to_cpu(s[0]);
 894        R = le32_to_cpu(s[1]);
 895
 896        IP(L, R, A);
 897        for (i = 0; i < 8; i++) {
 898                ROUND(L, R, A, B, K, 2);
 899                ROUND(R, L, A, B, K, 2);
 900        }
 901        for (i = 0; i < 8; i++) {
 902                ROUND(R, L, A, B, K, 2);
 903                ROUND(L, R, A, B, K, 2);
 904        }
 905        for (i = 0; i < 8; i++) {
 906                ROUND(L, R, A, B, K, 2);
 907                ROUND(R, L, A, B, K, 2);
 908        }
 909        FP(R, L, A);
 910
 911        d[0] = cpu_to_le32(R);
 912        d[1] = cpu_to_le32(L);
 913}
 914
 915static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 916{
 917        struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
 918        const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2;
 919        const __le32 *s = (const __le32 *)src;
 920        __le32 *d = (__le32 *)dst;
 921        u32 L, R, A, B;
 922        int i;
 923
 924        L = le32_to_cpu(s[0]);
 925        R = le32_to_cpu(s[1]);
 926
 927        IP(L, R, A);
 928        for (i = 0; i < 8; i++) {
 929                ROUND(L, R, A, B, K, -2);
 930                ROUND(R, L, A, B, K, -2);
 931        }
 932        for (i = 0; i < 8; i++) {
 933                ROUND(R, L, A, B, K, -2);
 934                ROUND(L, R, A, B, K, -2);
 935        }
 936        for (i = 0; i < 8; i++) {
 937                ROUND(L, R, A, B, K, -2);
 938                ROUND(R, L, A, B, K, -2);
 939        }
 940        FP(R, L, A);
 941
 942        d[0] = cpu_to_le32(R);
 943        d[1] = cpu_to_le32(L);
 944}
 945
 946static struct crypto_alg des_alg = {
 947        .cra_name               =       "des",
 948        .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
 949        .cra_blocksize          =       DES_BLOCK_SIZE,
 950        .cra_ctxsize            =       sizeof(struct des_ctx),
 951        .cra_module             =       THIS_MODULE,
 952        .cra_alignmask          =       3,
 953        .cra_list               =       LIST_HEAD_INIT(des_alg.cra_list),
 954        .cra_u                  =       { .cipher = {
 955        .cia_min_keysize        =       DES_KEY_SIZE,
 956        .cia_max_keysize        =       DES_KEY_SIZE,
 957        .cia_setkey             =       des_setkey,
 958        .cia_encrypt            =       des_encrypt,
 959        .cia_decrypt            =       des_decrypt } }
 960};
 961
 962static struct crypto_alg des3_ede_alg = {
 963        .cra_name               =       "des3_ede",
 964        .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
 965        .cra_blocksize          =       DES3_EDE_BLOCK_SIZE,
 966        .cra_ctxsize            =       sizeof(struct des3_ede_ctx),
 967        .cra_module             =       THIS_MODULE,
 968        .cra_alignmask          =       3,
 969        .cra_list               =       LIST_HEAD_INIT(des3_ede_alg.cra_list),
 970        .cra_u                  =       { .cipher = {
 971        .cia_min_keysize        =       DES3_EDE_KEY_SIZE,
 972        .cia_max_keysize        =       DES3_EDE_KEY_SIZE,
 973        .cia_setkey             =       des3_ede_setkey,
 974        .cia_encrypt            =       des3_ede_encrypt,
 975        .cia_decrypt            =       des3_ede_decrypt } }
 976};
 977
 978MODULE_ALIAS("des3_ede");
 979
 980static int __init des_generic_mod_init(void)
 981{
 982        int ret = 0;
 983
 984        ret = crypto_register_alg(&des_alg);
 985        if (ret < 0)
 986                goto out;
 987
 988        ret = crypto_register_alg(&des3_ede_alg);
 989        if (ret < 0)
 990                crypto_unregister_alg(&des_alg);
 991out:
 992        return ret;
 993}
 994
 995static void __exit des_generic_mod_fini(void)
 996{
 997        crypto_unregister_alg(&des3_ede_alg);
 998        crypto_unregister_alg(&des_alg);
 999}
1000
1001module_init(des_generic_mod_init);
1002module_exit(des_generic_mod_fini);
1003
1004MODULE_LICENSE("GPL");
1005MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
1006MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>");
1007MODULE_ALIAS("des");
1008