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