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