Back to home page

LXR

 
 

    


0001 /*
0002  * Cryptographic API.
0003  *
0004  * DES & Triple DES EDE Cipher Algorithms.
0005  *
0006  * Copyright (c) 2005 Dag Arne Osvik <da@osvik.no>
0007  *
0008  * This program is free software; you can redistribute it and/or modify
0009  * it under the terms of the GNU General Public License as published by
0010  * the Free Software Foundation; either version 2 of the License, or
0011  * (at your option) any later version.
0012  *
0013  */
0014 
0015 #include <asm/byteorder.h>
0016 #include <linux/bitops.h>
0017 #include <linux/init.h>
0018 #include <linux/module.h>
0019 #include <linux/errno.h>
0020 #include <linux/crypto.h>
0021 #include <linux/types.h>
0022 
0023 #include <crypto/des.h>
0024 
0025 #define ROL(x, r) ((x) = rol32((x), (r)))
0026 #define ROR(x, r) ((x) = ror32((x), (r)))
0027 
0028 struct des_ctx {
0029     u32 expkey[DES_EXPKEY_WORDS];
0030 };
0031 
0032 struct des3_ede_ctx {
0033     u32 expkey[DES3_EDE_EXPKEY_WORDS];
0034 };
0035 
0036 /* Lookup tables for key expansion */
0037 
0038 static const u8 pc1[256] = {
0039     0x00, 0x00, 0x40, 0x04, 0x10, 0x10, 0x50, 0x14,
0040     0x04, 0x40, 0x44, 0x44, 0x14, 0x50, 0x54, 0x54,
0041     0x02, 0x02, 0x42, 0x06, 0x12, 0x12, 0x52, 0x16,
0042     0x06, 0x42, 0x46, 0x46, 0x16, 0x52, 0x56, 0x56,
0043     0x80, 0x08, 0xc0, 0x0c, 0x90, 0x18, 0xd0, 0x1c,
0044     0x84, 0x48, 0xc4, 0x4c, 0x94, 0x58, 0xd4, 0x5c,
0045     0x82, 0x0a, 0xc2, 0x0e, 0x92, 0x1a, 0xd2, 0x1e,
0046     0x86, 0x4a, 0xc6, 0x4e, 0x96, 0x5a, 0xd6, 0x5e,
0047     0x20, 0x20, 0x60, 0x24, 0x30, 0x30, 0x70, 0x34,
0048     0x24, 0x60, 0x64, 0x64, 0x34, 0x70, 0x74, 0x74,
0049     0x22, 0x22, 0x62, 0x26, 0x32, 0x32, 0x72, 0x36,
0050     0x26, 0x62, 0x66, 0x66, 0x36, 0x72, 0x76, 0x76,
0051     0xa0, 0x28, 0xe0, 0x2c, 0xb0, 0x38, 0xf0, 0x3c,
0052     0xa4, 0x68, 0xe4, 0x6c, 0xb4, 0x78, 0xf4, 0x7c,
0053     0xa2, 0x2a, 0xe2, 0x2e, 0xb2, 0x3a, 0xf2, 0x3e,
0054     0xa6, 0x6a, 0xe6, 0x6e, 0xb6, 0x7a, 0xf6, 0x7e,
0055     0x08, 0x80, 0x48, 0x84, 0x18, 0x90, 0x58, 0x94,
0056     0x0c, 0xc0, 0x4c, 0xc4, 0x1c, 0xd0, 0x5c, 0xd4,
0057     0x0a, 0x82, 0x4a, 0x86, 0x1a, 0x92, 0x5a, 0x96,
0058     0x0e, 0xc2, 0x4e, 0xc6, 0x1e, 0xd2, 0x5e, 0xd6,
0059     0x88, 0x88, 0xc8, 0x8c, 0x98, 0x98, 0xd8, 0x9c,
0060     0x8c, 0xc8, 0xcc, 0xcc, 0x9c, 0xd8, 0xdc, 0xdc,
0061     0x8a, 0x8a, 0xca, 0x8e, 0x9a, 0x9a, 0xda, 0x9e,
0062     0x8e, 0xca, 0xce, 0xce, 0x9e, 0xda, 0xde, 0xde,
0063     0x28, 0xa0, 0x68, 0xa4, 0x38, 0xb0, 0x78, 0xb4,
0064     0x2c, 0xe0, 0x6c, 0xe4, 0x3c, 0xf0, 0x7c, 0xf4,
0065     0x2a, 0xa2, 0x6a, 0xa6, 0x3a, 0xb2, 0x7a, 0xb6,
0066     0x2e, 0xe2, 0x6e, 0xe6, 0x3e, 0xf2, 0x7e, 0xf6,
0067     0xa8, 0xa8, 0xe8, 0xac, 0xb8, 0xb8, 0xf8, 0xbc,
0068     0xac, 0xe8, 0xec, 0xec, 0xbc, 0xf8, 0xfc, 0xfc,
0069     0xaa, 0xaa, 0xea, 0xae, 0xba, 0xba, 0xfa, 0xbe,
0070     0xae, 0xea, 0xee, 0xee, 0xbe, 0xfa, 0xfe, 0xfe
0071 };
0072 
0073 static const u8 rs[256] = {
0074     0x00, 0x00, 0x80, 0x80, 0x02, 0x02, 0x82, 0x82,
0075     0x04, 0x04, 0x84, 0x84, 0x06, 0x06, 0x86, 0x86,
0076     0x08, 0x08, 0x88, 0x88, 0x0a, 0x0a, 0x8a, 0x8a,
0077     0x0c, 0x0c, 0x8c, 0x8c, 0x0e, 0x0e, 0x8e, 0x8e,
0078     0x10, 0x10, 0x90, 0x90, 0x12, 0x12, 0x92, 0x92,
0079     0x14, 0x14, 0x94, 0x94, 0x16, 0x16, 0x96, 0x96,
0080     0x18, 0x18, 0x98, 0x98, 0x1a, 0x1a, 0x9a, 0x9a,
0081     0x1c, 0x1c, 0x9c, 0x9c, 0x1e, 0x1e, 0x9e, 0x9e,
0082     0x20, 0x20, 0xa0, 0xa0, 0x22, 0x22, 0xa2, 0xa2,
0083     0x24, 0x24, 0xa4, 0xa4, 0x26, 0x26, 0xa6, 0xa6,
0084     0x28, 0x28, 0xa8, 0xa8, 0x2a, 0x2a, 0xaa, 0xaa,
0085     0x2c, 0x2c, 0xac, 0xac, 0x2e, 0x2e, 0xae, 0xae,
0086     0x30, 0x30, 0xb0, 0xb0, 0x32, 0x32, 0xb2, 0xb2,
0087     0x34, 0x34, 0xb4, 0xb4, 0x36, 0x36, 0xb6, 0xb6,
0088     0x38, 0x38, 0xb8, 0xb8, 0x3a, 0x3a, 0xba, 0xba,
0089     0x3c, 0x3c, 0xbc, 0xbc, 0x3e, 0x3e, 0xbe, 0xbe,
0090     0x40, 0x40, 0xc0, 0xc0, 0x42, 0x42, 0xc2, 0xc2,
0091     0x44, 0x44, 0xc4, 0xc4, 0x46, 0x46, 0xc6, 0xc6,
0092     0x48, 0x48, 0xc8, 0xc8, 0x4a, 0x4a, 0xca, 0xca,
0093     0x4c, 0x4c, 0xcc, 0xcc, 0x4e, 0x4e, 0xce, 0xce,
0094     0x50, 0x50, 0xd0, 0xd0, 0x52, 0x52, 0xd2, 0xd2,
0095     0x54, 0x54, 0xd4, 0xd4, 0x56, 0x56, 0xd6, 0xd6,
0096     0x58, 0x58, 0xd8, 0xd8, 0x5a, 0x5a, 0xda, 0xda,
0097     0x5c, 0x5c, 0xdc, 0xdc, 0x5e, 0x5e, 0xde, 0xde,
0098     0x60, 0x60, 0xe0, 0xe0, 0x62, 0x62, 0xe2, 0xe2,
0099     0x64, 0x64, 0xe4, 0xe4, 0x66, 0x66, 0xe6, 0xe6,
0100     0x68, 0x68, 0xe8, 0xe8, 0x6a, 0x6a, 0xea, 0xea,
0101     0x6c, 0x6c, 0xec, 0xec, 0x6e, 0x6e, 0xee, 0xee,
0102     0x70, 0x70, 0xf0, 0xf0, 0x72, 0x72, 0xf2, 0xf2,
0103     0x74, 0x74, 0xf4, 0xf4, 0x76, 0x76, 0xf6, 0xf6,
0104     0x78, 0x78, 0xf8, 0xf8, 0x7a, 0x7a, 0xfa, 0xfa,
0105     0x7c, 0x7c, 0xfc, 0xfc, 0x7e, 0x7e, 0xfe, 0xfe
0106 };
0107 
0108 static const u32 pc2[1024] = {
0109     0x00000000, 0x00000000, 0x00000000, 0x00000000,
0110     0x00040000, 0x00000000, 0x04000000, 0x00100000,
0111     0x00400000, 0x00000008, 0x00000800, 0x40000000,
0112     0x00440000, 0x00000008, 0x04000800, 0x40100000,
0113     0x00000400, 0x00000020, 0x08000000, 0x00000100,
0114     0x00040400, 0x00000020, 0x0c000000, 0x00100100,
0115     0x00400400, 0x00000028, 0x08000800, 0x40000100,
0116     0x00440400, 0x00000028, 0x0c000800, 0x40100100,
0117     0x80000000, 0x00000010, 0x00000000, 0x00800000,
0118     0x80040000, 0x00000010, 0x04000000, 0x00900000,
0119     0x80400000, 0x00000018, 0x00000800, 0x40800000,
0120     0x80440000, 0x00000018, 0x04000800, 0x40900000,
0121     0x80000400, 0x00000030, 0x08000000, 0x00800100,
0122     0x80040400, 0x00000030, 0x0c000000, 0x00900100,
0123     0x80400400, 0x00000038, 0x08000800, 0x40800100,
0124     0x80440400, 0x00000038, 0x0c000800, 0x40900100,
0125     0x10000000, 0x00000000, 0x00200000, 0x00001000,
0126     0x10040000, 0x00000000, 0x04200000, 0x00101000,
0127     0x10400000, 0x00000008, 0x00200800, 0x40001000,
0128     0x10440000, 0x00000008, 0x04200800, 0x40101000,
0129     0x10000400, 0x00000020, 0x08200000, 0x00001100,
0130     0x10040400, 0x00000020, 0x0c200000, 0x00101100,
0131     0x10400400, 0x00000028, 0x08200800, 0x40001100,
0132     0x10440400, 0x00000028, 0x0c200800, 0x40101100,
0133     0x90000000, 0x00000010, 0x00200000, 0x00801000,
0134     0x90040000, 0x00000010, 0x04200000, 0x00901000,
0135     0x90400000, 0x00000018, 0x00200800, 0x40801000,
0136     0x90440000, 0x00000018, 0x04200800, 0x40901000,
0137     0x90000400, 0x00000030, 0x08200000, 0x00801100,
0138     0x90040400, 0x00000030, 0x0c200000, 0x00901100,
0139     0x90400400, 0x00000038, 0x08200800, 0x40801100,
0140     0x90440400, 0x00000038, 0x0c200800, 0x40901100,
0141     0x00000200, 0x00080000, 0x00000000, 0x00000004,
0142     0x00040200, 0x00080000, 0x04000000, 0x00100004,
0143     0x00400200, 0x00080008, 0x00000800, 0x40000004,
0144     0x00440200, 0x00080008, 0x04000800, 0x40100004,
0145     0x00000600, 0x00080020, 0x08000000, 0x00000104,
0146     0x00040600, 0x00080020, 0x0c000000, 0x00100104,
0147     0x00400600, 0x00080028, 0x08000800, 0x40000104,
0148     0x00440600, 0x00080028, 0x0c000800, 0x40100104,
0149     0x80000200, 0x00080010, 0x00000000, 0x00800004,
0150     0x80040200, 0x00080010, 0x04000000, 0x00900004,
0151     0x80400200, 0x00080018, 0x00000800, 0x40800004,
0152     0x80440200, 0x00080018, 0x04000800, 0x40900004,
0153     0x80000600, 0x00080030, 0x08000000, 0x00800104,
0154     0x80040600, 0x00080030, 0x0c000000, 0x00900104,
0155     0x80400600, 0x00080038, 0x08000800, 0x40800104,
0156     0x80440600, 0x00080038, 0x0c000800, 0x40900104,
0157     0x10000200, 0x00080000, 0x00200000, 0x00001004,
0158     0x10040200, 0x00080000, 0x04200000, 0x00101004,
0159     0x10400200, 0x00080008, 0x00200800, 0x40001004,
0160     0x10440200, 0x00080008, 0x04200800, 0x40101004,
0161     0x10000600, 0x00080020, 0x08200000, 0x00001104,
0162     0x10040600, 0x00080020, 0x0c200000, 0x00101104,
0163     0x10400600, 0x00080028, 0x08200800, 0x40001104,
0164     0x10440600, 0x00080028, 0x0c200800, 0x40101104,
0165     0x90000200, 0x00080010, 0x00200000, 0x00801004,
0166     0x90040200, 0x00080010, 0x04200000, 0x00901004,
0167     0x90400200, 0x00080018, 0x00200800, 0x40801004,
0168     0x90440200, 0x00080018, 0x04200800, 0x40901004,
0169     0x90000600, 0x00080030, 0x08200000, 0x00801104,
0170     0x90040600, 0x00080030, 0x0c200000, 0x00901104,
0171     0x90400600, 0x00080038, 0x08200800, 0x40801104,
0172     0x90440600, 0x00080038, 0x0c200800, 0x40901104,
0173     0x00000002, 0x00002000, 0x20000000, 0x00000001,
0174     0x00040002, 0x00002000, 0x24000000, 0x00100001,
0175     0x00400002, 0x00002008, 0x20000800, 0x40000001,
0176     0x00440002, 0x00002008, 0x24000800, 0x40100001,
0177     0x00000402, 0x00002020, 0x28000000, 0x00000101,
0178     0x00040402, 0x00002020, 0x2c000000, 0x00100101,
0179     0x00400402, 0x00002028, 0x28000800, 0x40000101,
0180     0x00440402, 0x00002028, 0x2c000800, 0x40100101,
0181     0x80000002, 0x00002010, 0x20000000, 0x00800001,
0182     0x80040002, 0x00002010, 0x24000000, 0x00900001,
0183     0x80400002, 0x00002018, 0x20000800, 0x40800001,
0184     0x80440002, 0x00002018, 0x24000800, 0x40900001,
0185     0x80000402, 0x00002030, 0x28000000, 0x00800101,
0186     0x80040402, 0x00002030, 0x2c000000, 0x00900101,
0187     0x80400402, 0x00002038, 0x28000800, 0x40800101,
0188     0x80440402, 0x00002038, 0x2c000800, 0x40900101,
0189     0x10000002, 0x00002000, 0x20200000, 0x00001001,
0190     0x10040002, 0x00002000, 0x24200000, 0x00101001,
0191     0x10400002, 0x00002008, 0x20200800, 0x40001001,
0192     0x10440002, 0x00002008, 0x24200800, 0x40101001,
0193     0x10000402, 0x00002020, 0x28200000, 0x00001101,
0194     0x10040402, 0x00002020, 0x2c200000, 0x00101101,
0195     0x10400402, 0x00002028, 0x28200800, 0x40001101,
0196     0x10440402, 0x00002028, 0x2c200800, 0x40101101,
0197     0x90000002, 0x00002010, 0x20200000, 0x00801001,
0198     0x90040002, 0x00002010, 0x24200000, 0x00901001,
0199     0x90400002, 0x00002018, 0x20200800, 0x40801001,
0200     0x90440002, 0x00002018, 0x24200800, 0x40901001,
0201     0x90000402, 0x00002030, 0x28200000, 0x00801101,
0202     0x90040402, 0x00002030, 0x2c200000, 0x00901101,
0203     0x90400402, 0x00002038, 0x28200800, 0x40801101,
0204     0x90440402, 0x00002038, 0x2c200800, 0x40901101,
0205     0x00000202, 0x00082000, 0x20000000, 0x00000005,
0206     0x00040202, 0x00082000, 0x24000000, 0x00100005,
0207     0x00400202, 0x00082008, 0x20000800, 0x40000005,
0208     0x00440202, 0x00082008, 0x24000800, 0x40100005,
0209     0x00000602, 0x00082020, 0x28000000, 0x00000105,
0210     0x00040602, 0x00082020, 0x2c000000, 0x00100105,
0211     0x00400602, 0x00082028, 0x28000800, 0x40000105,
0212     0x00440602, 0x00082028, 0x2c000800, 0x40100105,
0213     0x80000202, 0x00082010, 0x20000000, 0x00800005,
0214     0x80040202, 0x00082010, 0x24000000, 0x00900005,
0215     0x80400202, 0x00082018, 0x20000800, 0x40800005,
0216     0x80440202, 0x00082018, 0x24000800, 0x40900005,
0217     0x80000602, 0x00082030, 0x28000000, 0x00800105,
0218     0x80040602, 0x00082030, 0x2c000000, 0x00900105,
0219     0x80400602, 0x00082038, 0x28000800, 0x40800105,
0220     0x80440602, 0x00082038, 0x2c000800, 0x40900105,
0221     0x10000202, 0x00082000, 0x20200000, 0x00001005,
0222     0x10040202, 0x00082000, 0x24200000, 0x00101005,
0223     0x10400202, 0x00082008, 0x20200800, 0x40001005,
0224     0x10440202, 0x00082008, 0x24200800, 0x40101005,
0225     0x10000602, 0x00082020, 0x28200000, 0x00001105,
0226     0x10040602, 0x00082020, 0x2c200000, 0x00101105,
0227     0x10400602, 0x00082028, 0x28200800, 0x40001105,
0228     0x10440602, 0x00082028, 0x2c200800, 0x40101105,
0229     0x90000202, 0x00082010, 0x20200000, 0x00801005,
0230     0x90040202, 0x00082010, 0x24200000, 0x00901005,
0231     0x90400202, 0x00082018, 0x20200800, 0x40801005,
0232     0x90440202, 0x00082018, 0x24200800, 0x40901005,
0233     0x90000602, 0x00082030, 0x28200000, 0x00801105,
0234     0x90040602, 0x00082030, 0x2c200000, 0x00901105,
0235     0x90400602, 0x00082038, 0x28200800, 0x40801105,
0236     0x90440602, 0x00082038, 0x2c200800, 0x40901105,
0237 
0238     0x00000000, 0x00000000, 0x00000000, 0x00000000,
0239     0x00000000, 0x00000008, 0x00080000, 0x10000000,
0240     0x02000000, 0x00000000, 0x00000080, 0x00001000,
0241     0x02000000, 0x00000008, 0x00080080, 0x10001000,
0242     0x00004000, 0x00000000, 0x00000040, 0x00040000,
0243     0x00004000, 0x00000008, 0x00080040, 0x10040000,
0244     0x02004000, 0x00000000, 0x000000c0, 0x00041000,
0245     0x02004000, 0x00000008, 0x000800c0, 0x10041000,
0246     0x00020000, 0x00008000, 0x08000000, 0x00200000,
0247     0x00020000, 0x00008008, 0x08080000, 0x10200000,
0248     0x02020000, 0x00008000, 0x08000080, 0x00201000,
0249     0x02020000, 0x00008008, 0x08080080, 0x10201000,
0250     0x00024000, 0x00008000, 0x08000040, 0x00240000,
0251     0x00024000, 0x00008008, 0x08080040, 0x10240000,
0252     0x02024000, 0x00008000, 0x080000c0, 0x00241000,
0253     0x02024000, 0x00008008, 0x080800c0, 0x10241000,
0254     0x00000000, 0x01000000, 0x00002000, 0x00000020,
0255     0x00000000, 0x01000008, 0x00082000, 0x10000020,
0256     0x02000000, 0x01000000, 0x00002080, 0x00001020,
0257     0x02000000, 0x01000008, 0x00082080, 0x10001020,
0258     0x00004000, 0x01000000, 0x00002040, 0x00040020,
0259     0x00004000, 0x01000008, 0x00082040, 0x10040020,
0260     0x02004000, 0x01000000, 0x000020c0, 0x00041020,
0261     0x02004000, 0x01000008, 0x000820c0, 0x10041020,
0262     0x00020000, 0x01008000, 0x08002000, 0x00200020,
0263     0x00020000, 0x01008008, 0x08082000, 0x10200020,
0264     0x02020000, 0x01008000, 0x08002080, 0x00201020,
0265     0x02020000, 0x01008008, 0x08082080, 0x10201020,
0266     0x00024000, 0x01008000, 0x08002040, 0x00240020,
0267     0x00024000, 0x01008008, 0x08082040, 0x10240020,
0268     0x02024000, 0x01008000, 0x080020c0, 0x00241020,
0269     0x02024000, 0x01008008, 0x080820c0, 0x10241020,
0270     0x00000400, 0x04000000, 0x00100000, 0x00000004,
0271     0x00000400, 0x04000008, 0x00180000, 0x10000004,
0272     0x02000400, 0x04000000, 0x00100080, 0x00001004,
0273     0x02000400, 0x04000008, 0x00180080, 0x10001004,
0274     0x00004400, 0x04000000, 0x00100040, 0x00040004,
0275     0x00004400, 0x04000008, 0x00180040, 0x10040004,
0276     0x02004400, 0x04000000, 0x001000c0, 0x00041004,
0277     0x02004400, 0x04000008, 0x001800c0, 0x10041004,
0278     0x00020400, 0x04008000, 0x08100000, 0x00200004,
0279     0x00020400, 0x04008008, 0x08180000, 0x10200004,
0280     0x02020400, 0x04008000, 0x08100080, 0x00201004,
0281     0x02020400, 0x04008008, 0x08180080, 0x10201004,
0282     0x00024400, 0x04008000, 0x08100040, 0x00240004,
0283     0x00024400, 0x04008008, 0x08180040, 0x10240004,
0284     0x02024400, 0x04008000, 0x081000c0, 0x00241004,
0285     0x02024400, 0x04008008, 0x081800c0, 0x10241004,
0286     0x00000400, 0x05000000, 0x00102000, 0x00000024,
0287     0x00000400, 0x05000008, 0x00182000, 0x10000024,
0288     0x02000400, 0x05000000, 0x00102080, 0x00001024,
0289     0x02000400, 0x05000008, 0x00182080, 0x10001024,
0290     0x00004400, 0x05000000, 0x00102040, 0x00040024,
0291     0x00004400, 0x05000008, 0x00182040, 0x10040024,
0292     0x02004400, 0x05000000, 0x001020c0, 0x00041024,
0293     0x02004400, 0x05000008, 0x001820c0, 0x10041024,
0294     0x00020400, 0x05008000, 0x08102000, 0x00200024,
0295     0x00020400, 0x05008008, 0x08182000, 0x10200024,
0296     0x02020400, 0x05008000, 0x08102080, 0x00201024,
0297     0x02020400, 0x05008008, 0x08182080, 0x10201024,
0298     0x00024400, 0x05008000, 0x08102040, 0x00240024,
0299     0x00024400, 0x05008008, 0x08182040, 0x10240024,
0300     0x02024400, 0x05008000, 0x081020c0, 0x00241024,
0301     0x02024400, 0x05008008, 0x081820c0, 0x10241024,
0302     0x00000800, 0x00010000, 0x20000000, 0x00000010,
0303     0x00000800, 0x00010008, 0x20080000, 0x10000010,
0304     0x02000800, 0x00010000, 0x20000080, 0x00001010,
0305     0x02000800, 0x00010008, 0x20080080, 0x10001010,
0306     0x00004800, 0x00010000, 0x20000040, 0x00040010,
0307     0x00004800, 0x00010008, 0x20080040, 0x10040010,
0308     0x02004800, 0x00010000, 0x200000c0, 0x00041010,
0309     0x02004800, 0x00010008, 0x200800c0, 0x10041010,
0310     0x00020800, 0x00018000, 0x28000000, 0x00200010,
0311     0x00020800, 0x00018008, 0x28080000, 0x10200010,
0312     0x02020800, 0x00018000, 0x28000080, 0x00201010,
0313     0x02020800, 0x00018008, 0x28080080, 0x10201010,
0314     0x00024800, 0x00018000, 0x28000040, 0x00240010,
0315     0x00024800, 0x00018008, 0x28080040, 0x10240010,
0316     0x02024800, 0x00018000, 0x280000c0, 0x00241010,
0317     0x02024800, 0x00018008, 0x280800c0, 0x10241010,
0318     0x00000800, 0x01010000, 0x20002000, 0x00000030,
0319     0x00000800, 0x01010008, 0x20082000, 0x10000030,
0320     0x02000800, 0x01010000, 0x20002080, 0x00001030,
0321     0x02000800, 0x01010008, 0x20082080, 0x10001030,
0322     0x00004800, 0x01010000, 0x20002040, 0x00040030,
0323     0x00004800, 0x01010008, 0x20082040, 0x10040030,
0324     0x02004800, 0x01010000, 0x200020c0, 0x00041030,
0325     0x02004800, 0x01010008, 0x200820c0, 0x10041030,
0326     0x00020800, 0x01018000, 0x28002000, 0x00200030,
0327     0x00020800, 0x01018008, 0x28082000, 0x10200030,
0328     0x02020800, 0x01018000, 0x28002080, 0x00201030,
0329     0x02020800, 0x01018008, 0x28082080, 0x10201030,
0330     0x00024800, 0x01018000, 0x28002040, 0x00240030,
0331     0x00024800, 0x01018008, 0x28082040, 0x10240030,
0332     0x02024800, 0x01018000, 0x280020c0, 0x00241030,
0333     0x02024800, 0x01018008, 0x280820c0, 0x10241030,
0334     0x00000c00, 0x04010000, 0x20100000, 0x00000014,
0335     0x00000c00, 0x04010008, 0x20180000, 0x10000014,
0336     0x02000c00, 0x04010000, 0x20100080, 0x00001014,
0337     0x02000c00, 0x04010008, 0x20180080, 0x10001014,
0338     0x00004c00, 0x04010000, 0x20100040, 0x00040014,
0339     0x00004c00, 0x04010008, 0x20180040, 0x10040014,
0340     0x02004c00, 0x04010000, 0x201000c0, 0x00041014,
0341     0x02004c00, 0x04010008, 0x201800c0, 0x10041014,
0342     0x00020c00, 0x04018000, 0x28100000, 0x00200014,
0343     0x00020c00, 0x04018008, 0x28180000, 0x10200014,
0344     0x02020c00, 0x04018000, 0x28100080, 0x00201014,
0345     0x02020c00, 0x04018008, 0x28180080, 0x10201014,
0346     0x00024c00, 0x04018000, 0x28100040, 0x00240014,
0347     0x00024c00, 0x04018008, 0x28180040, 0x10240014,
0348     0x02024c00, 0x04018000, 0x281000c0, 0x00241014,
0349     0x02024c00, 0x04018008, 0x281800c0, 0x10241014,
0350     0x00000c00, 0x05010000, 0x20102000, 0x00000034,
0351     0x00000c00, 0x05010008, 0x20182000, 0x10000034,
0352     0x02000c00, 0x05010000, 0x20102080, 0x00001034,
0353     0x02000c00, 0x05010008, 0x20182080, 0x10001034,
0354     0x00004c00, 0x05010000, 0x20102040, 0x00040034,
0355     0x00004c00, 0x05010008, 0x20182040, 0x10040034,
0356     0x02004c00, 0x05010000, 0x201020c0, 0x00041034,
0357     0x02004c00, 0x05010008, 0x201820c0, 0x10041034,
0358     0x00020c00, 0x05018000, 0x28102000, 0x00200034,
0359     0x00020c00, 0x05018008, 0x28182000, 0x10200034,
0360     0x02020c00, 0x05018000, 0x28102080, 0x00201034,
0361     0x02020c00, 0x05018008, 0x28182080, 0x10201034,
0362     0x00024c00, 0x05018000, 0x28102040, 0x00240034,
0363     0x00024c00, 0x05018008, 0x28182040, 0x10240034,
0364     0x02024c00, 0x05018000, 0x281020c0, 0x00241034,
0365     0x02024c00, 0x05018008, 0x281820c0, 0x10241034
0366 };
0367 
0368 /* S-box lookup tables */
0369 
0370 static const u32 S1[64] = {
0371     0x01010400, 0x00000000, 0x00010000, 0x01010404,
0372     0x01010004, 0x00010404, 0x00000004, 0x00010000,
0373     0x00000400, 0x01010400, 0x01010404, 0x00000400,
0374     0x01000404, 0x01010004, 0x01000000, 0x00000004,
0375     0x00000404, 0x01000400, 0x01000400, 0x00010400,
0376     0x00010400, 0x01010000, 0x01010000, 0x01000404,
0377     0x00010004, 0x01000004, 0x01000004, 0x00010004,
0378     0x00000000, 0x00000404, 0x00010404, 0x01000000,
0379     0x00010000, 0x01010404, 0x00000004, 0x01010000,
0380     0x01010400, 0x01000000, 0x01000000, 0x00000400,
0381     0x01010004, 0x00010000, 0x00010400, 0x01000004,
0382     0x00000400, 0x00000004, 0x01000404, 0x00010404,
0383     0x01010404, 0x00010004, 0x01010000, 0x01000404,
0384     0x01000004, 0x00000404, 0x00010404, 0x01010400,
0385     0x00000404, 0x01000400, 0x01000400, 0x00000000,
0386     0x00010004, 0x00010400, 0x00000000, 0x01010004
0387 };
0388 
0389 static const u32 S2[64] = {
0390     0x80108020, 0x80008000, 0x00008000, 0x00108020,
0391     0x00100000, 0x00000020, 0x80100020, 0x80008020,
0392     0x80000020, 0x80108020, 0x80108000, 0x80000000,
0393     0x80008000, 0x00100000, 0x00000020, 0x80100020,
0394     0x00108000, 0x00100020, 0x80008020, 0x00000000,
0395     0x80000000, 0x00008000, 0x00108020, 0x80100000,
0396     0x00100020, 0x80000020, 0x00000000, 0x00108000,
0397     0x00008020, 0x80108000, 0x80100000, 0x00008020,
0398     0x00000000, 0x00108020, 0x80100020, 0x00100000,
0399     0x80008020, 0x80100000, 0x80108000, 0x00008000,
0400     0x80100000, 0x80008000, 0x00000020, 0x80108020,
0401     0x00108020, 0x00000020, 0x00008000, 0x80000000,
0402     0x00008020, 0x80108000, 0x00100000, 0x80000020,
0403     0x00100020, 0x80008020, 0x80000020, 0x00100020,
0404     0x00108000, 0x00000000, 0x80008000, 0x00008020,
0405     0x80000000, 0x80100020, 0x80108020, 0x00108000
0406 };
0407 
0408 static const u32 S3[64] = {
0409     0x00000208, 0x08020200, 0x00000000, 0x08020008,
0410     0x08000200, 0x00000000, 0x00020208, 0x08000200,
0411     0x00020008, 0x08000008, 0x08000008, 0x00020000,
0412     0x08020208, 0x00020008, 0x08020000, 0x00000208,
0413     0x08000000, 0x00000008, 0x08020200, 0x00000200,
0414     0x00020200, 0x08020000, 0x08020008, 0x00020208,
0415     0x08000208, 0x00020200, 0x00020000, 0x08000208,
0416     0x00000008, 0x08020208, 0x00000200, 0x08000000,
0417     0x08020200, 0x08000000, 0x00020008, 0x00000208,
0418     0x00020000, 0x08020200, 0x08000200, 0x00000000,
0419     0x00000200, 0x00020008, 0x08020208, 0x08000200,
0420     0x08000008, 0x00000200, 0x00000000, 0x08020008,
0421     0x08000208, 0x00020000, 0x08000000, 0x08020208,
0422     0x00000008, 0x00020208, 0x00020200, 0x08000008,
0423     0x08020000, 0x08000208, 0x00000208, 0x08020000,
0424     0x00020208, 0x00000008, 0x08020008, 0x00020200
0425 };
0426 
0427 static const u32 S4[64] = {
0428     0x00802001, 0x00002081, 0x00002081, 0x00000080,
0429     0x00802080, 0x00800081, 0x00800001, 0x00002001,
0430     0x00000000, 0x00802000, 0x00802000, 0x00802081,
0431     0x00000081, 0x00000000, 0x00800080, 0x00800001,
0432     0x00000001, 0x00002000, 0x00800000, 0x00802001,
0433     0x00000080, 0x00800000, 0x00002001, 0x00002080,
0434     0x00800081, 0x00000001, 0x00002080, 0x00800080,
0435     0x00002000, 0x00802080, 0x00802081, 0x00000081,
0436     0x00800080, 0x00800001, 0x00802000, 0x00802081,
0437     0x00000081, 0x00000000, 0x00000000, 0x00802000,
0438     0x00002080, 0x00800080, 0x00800081, 0x00000001,
0439     0x00802001, 0x00002081, 0x00002081, 0x00000080,
0440     0x00802081, 0x00000081, 0x00000001, 0x00002000,
0441     0x00800001, 0x00002001, 0x00802080, 0x00800081,
0442     0x00002001, 0x00002080, 0x00800000, 0x00802001,
0443     0x00000080, 0x00800000, 0x00002000, 0x00802080
0444 };
0445 
0446 static const u32 S5[64] = {
0447     0x00000100, 0x02080100, 0x02080000, 0x42000100,
0448     0x00080000, 0x00000100, 0x40000000, 0x02080000,
0449     0x40080100, 0x00080000, 0x02000100, 0x40080100,
0450     0x42000100, 0x42080000, 0x00080100, 0x40000000,
0451     0x02000000, 0x40080000, 0x40080000, 0x00000000,
0452     0x40000100, 0x42080100, 0x42080100, 0x02000100,
0453     0x42080000, 0x40000100, 0x00000000, 0x42000000,
0454     0x02080100, 0x02000000, 0x42000000, 0x00080100,
0455     0x00080000, 0x42000100, 0x00000100, 0x02000000,
0456     0x40000000, 0x02080000, 0x42000100, 0x40080100,
0457     0x02000100, 0x40000000, 0x42080000, 0x02080100,
0458     0x40080100, 0x00000100, 0x02000000, 0x42080000,
0459     0x42080100, 0x00080100, 0x42000000, 0x42080100,
0460     0x02080000, 0x00000000, 0x40080000, 0x42000000,
0461     0x00080100, 0x02000100, 0x40000100, 0x00080000,
0462     0x00000000, 0x40080000, 0x02080100, 0x40000100
0463 };
0464 
0465 static const u32 S6[64] = {
0466     0x20000010, 0x20400000, 0x00004000, 0x20404010,
0467     0x20400000, 0x00000010, 0x20404010, 0x00400000,
0468     0x20004000, 0x00404010, 0x00400000, 0x20000010,
0469     0x00400010, 0x20004000, 0x20000000, 0x00004010,
0470     0x00000000, 0x00400010, 0x20004010, 0x00004000,
0471     0x00404000, 0x20004010, 0x00000010, 0x20400010,
0472     0x20400010, 0x00000000, 0x00404010, 0x20404000,
0473     0x00004010, 0x00404000, 0x20404000, 0x20000000,
0474     0x20004000, 0x00000010, 0x20400010, 0x00404000,
0475     0x20404010, 0x00400000, 0x00004010, 0x20000010,
0476     0x00400000, 0x20004000, 0x20000000, 0x00004010,
0477     0x20000010, 0x20404010, 0x00404000, 0x20400000,
0478     0x00404010, 0x20404000, 0x00000000, 0x20400010,
0479     0x00000010, 0x00004000, 0x20400000, 0x00404010,
0480     0x00004000, 0x00400010, 0x20004010, 0x00000000,
0481     0x20404000, 0x20000000, 0x00400010, 0x20004010
0482 };
0483 
0484 static const u32 S7[64] = {
0485     0x00200000, 0x04200002, 0x04000802, 0x00000000,
0486     0x00000800, 0x04000802, 0x00200802, 0x04200800,
0487     0x04200802, 0x00200000, 0x00000000, 0x04000002,
0488     0x00000002, 0x04000000, 0x04200002, 0x00000802,
0489     0x04000800, 0x00200802, 0x00200002, 0x04000800,
0490     0x04000002, 0x04200000, 0x04200800, 0x00200002,
0491     0x04200000, 0x00000800, 0x00000802, 0x04200802,
0492     0x00200800, 0x00000002, 0x04000000, 0x00200800,
0493     0x04000000, 0x00200800, 0x00200000, 0x04000802,
0494     0x04000802, 0x04200002, 0x04200002, 0x00000002,
0495     0x00200002, 0x04000000, 0x04000800, 0x00200000,
0496     0x04200800, 0x00000802, 0x00200802, 0x04200800,
0497     0x00000802, 0x04000002, 0x04200802, 0x04200000,
0498     0x00200800, 0x00000000, 0x00000002, 0x04200802,
0499     0x00000000, 0x00200802, 0x04200000, 0x00000800,
0500     0x04000002, 0x04000800, 0x00000800, 0x00200002
0501 };
0502 
0503 static const u32 S8[64] = {
0504     0x10001040, 0x00001000, 0x00040000, 0x10041040,
0505     0x10000000, 0x10001040, 0x00000040, 0x10000000,
0506     0x00040040, 0x10040000, 0x10041040, 0x00041000,
0507     0x10041000, 0x00041040, 0x00001000, 0x00000040,
0508     0x10040000, 0x10000040, 0x10001000, 0x00001040,
0509     0x00041000, 0x00040040, 0x10040040, 0x10041000,
0510     0x00001040, 0x00000000, 0x00000000, 0x10040040,
0511     0x10000040, 0x10001000, 0x00041040, 0x00040000,
0512     0x00041040, 0x00040000, 0x10041000, 0x00001000,
0513     0x00000040, 0x10040040, 0x00001000, 0x00041040,
0514     0x10001000, 0x00000040, 0x10000040, 0x10040000,
0515     0x10040040, 0x10000000, 0x00040000, 0x10001040,
0516     0x00000000, 0x10041040, 0x00040040, 0x10000040,
0517     0x10040000, 0x10001000, 0x10001040, 0x00000000,
0518     0x10041040, 0x00041000, 0x00041000, 0x00001040,
0519     0x00001040, 0x00040040, 0x10000000, 0x10041000
0520 };
0521 
0522 /* Encryption components: IP, FP, and round function */
0523 
0524 #define IP(L, R, T)     \
0525     ROL(R, 4);      \
0526     T  = L;         \
0527     L ^= R;         \
0528     L &= 0xf0f0f0f0;    \
0529     R ^= L;         \
0530     L ^= T;         \
0531     ROL(R, 12);     \
0532     T  = L;         \
0533     L ^= R;         \
0534     L &= 0xffff0000;    \
0535     R ^= L;         \
0536     L ^= T;         \
0537     ROR(R, 14);     \
0538     T  = L;         \
0539     L ^= R;         \
0540     L &= 0xcccccccc;    \
0541     R ^= L;         \
0542     L ^= T;         \
0543     ROL(R, 6);      \
0544     T  = L;         \
0545     L ^= R;         \
0546     L &= 0xff00ff00;    \
0547     R ^= L;         \
0548     L ^= T;         \
0549     ROR(R, 7);      \
0550     T  = L;         \
0551     L ^= R;         \
0552     L &= 0xaaaaaaaa;    \
0553     R ^= L;         \
0554     L ^= T;         \
0555     ROL(L, 1);
0556 
0557 #define FP(L, R, T)     \
0558     ROR(L, 1);      \
0559     T  = L;         \
0560     L ^= R;         \
0561     L &= 0xaaaaaaaa;    \
0562     R ^= L;         \
0563     L ^= T;         \
0564     ROL(R, 7);      \
0565     T  = L;         \
0566     L ^= R;         \
0567     L &= 0xff00ff00;    \
0568     R ^= L;         \
0569     L ^= T;         \
0570     ROR(R, 6);      \
0571     T  = L;         \
0572     L ^= R;         \
0573     L &= 0xcccccccc;    \
0574     R ^= L;         \
0575     L ^= T;         \
0576     ROL(R, 14);     \
0577     T  = L;         \
0578     L ^= R;         \
0579     L &= 0xffff0000;    \
0580     R ^= L;         \
0581     L ^= T;         \
0582     ROR(R, 12);     \
0583     T  = L;         \
0584     L ^= R;         \
0585     L &= 0xf0f0f0f0;    \
0586     R ^= L;         \
0587     L ^= T;         \
0588     ROR(R, 4);
0589 
0590 #define ROUND(L, R, A, B, K, d)                 \
0591     B = K[0];           A = K[1];   K += d; \
0592     B ^= R;             A ^= R;         \
0593     B &= 0x3f3f3f3f;        ROR(A, 4);      \
0594     L ^= S8[0xff & B];      A &= 0x3f3f3f3f;    \
0595     L ^= S6[0xff & (B >> 8)];   B >>= 16;       \
0596     L ^= S7[0xff & A];                  \
0597     L ^= S5[0xff & (A >> 8)];   A >>= 16;       \
0598     L ^= S4[0xff & B];                  \
0599     L ^= S2[0xff & (B >> 8)];               \
0600     L ^= S3[0xff & A];                  \
0601     L ^= S1[0xff & (A >> 8)];
0602 
0603 /*
0604  * PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved
0605  * tables of 128 elements.  One set is for C_i and the other for D_i, while
0606  * the 4 interleaved tables correspond to four 7-bit subsets of C_i or D_i.
0607  *
0608  * After PC1 each of the variables a,b,c,d contains a 7 bit subset of C_i
0609  * or D_i in bits 7-1 (bit 0 being the least significant).
0610  */
0611 
0612 #define T1(x) pt[2 * (x) + 0]
0613 #define T2(x) pt[2 * (x) + 1]
0614 #define T3(x) pt[2 * (x) + 2]
0615 #define T4(x) pt[2 * (x) + 3]
0616 
0617 #define DES_PC2(a, b, c, d) (T4(d) | T3(c) | T2(b) | T1(a))
0618 
0619 /*
0620  * Encryption key expansion
0621  *
0622  * RFC2451: Weak key checks SHOULD be performed.
0623  *
0624  * FIPS 74:
0625  *
0626  *   Keys having duals are keys which produce all zeros, all ones, or
0627  *   alternating zero-one patterns in the C and D registers after Permuted
0628  *   Choice 1 has operated on the key.
0629  *
0630  */
0631 unsigned long des_ekey(u32 *pe, const u8 *k)
0632 {
0633     /* K&R: long is at least 32 bits */
0634     unsigned long a, b, c, d, w;
0635     const u32 *pt = pc2;
0636 
0637     d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
0638     c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
0639     b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
0640     a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
0641 
0642     pe[15 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d];
0643     pe[14 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0644     pe[13 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0645     pe[12 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0646     pe[11 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0647     pe[10 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0648     pe[ 9 * 2 + 0] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0649     pe[ 8 * 2 + 0] = DES_PC2(d, a, b, c); c = rs[c];
0650     pe[ 7 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0651     pe[ 6 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0652     pe[ 5 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0653     pe[ 4 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0654     pe[ 3 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0655     pe[ 2 * 2 + 0] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0656     pe[ 1 * 2 + 0] = DES_PC2(c, d, a, b); b = rs[b];
0657     pe[ 0 * 2 + 0] = DES_PC2(b, c, d, a);
0658 
0659     /* Check if first half is weak */
0660     w  = (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
0661 
0662     /* Skip to next table set */
0663     pt += 512;
0664 
0665     d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
0666     c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
0667     b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
0668     a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
0669 
0670     /* Check if second half is weak */
0671     w |= (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
0672 
0673     pe[15 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d];
0674     pe[14 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0675     pe[13 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0676     pe[12 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0677     pe[11 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0678     pe[10 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0679     pe[ 9 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0680     pe[ 8 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c];
0681     pe[ 7 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0682     pe[ 6 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0683     pe[ 5 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0684     pe[ 4 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0685     pe[ 3 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0686     pe[ 2 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0687     pe[ 1 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b];
0688     pe[ 0 * 2 + 1] = DES_PC2(b, c, d, a);
0689 
0690     /* Fixup: 2413 5768 -> 1357 2468 */
0691     for (d = 0; d < 16; ++d) {
0692         a = pe[2 * d];
0693         b = pe[2 * d + 1];
0694         c = a ^ b;
0695         c &= 0xffff0000;
0696         a ^= c;
0697         b ^= c;
0698         ROL(b, 18);
0699         pe[2 * d] = a;
0700         pe[2 * d + 1] = b;
0701     }
0702 
0703     /* Zero if weak key */
0704     return w;
0705 }
0706 EXPORT_SYMBOL_GPL(des_ekey);
0707 
0708 /*
0709  * Decryption key expansion
0710  *
0711  * No weak key checking is performed, as this is only used by triple DES
0712  *
0713  */
0714 static void dkey(u32 *pe, const u8 *k)
0715 {
0716     /* K&R: long is at least 32 bits */
0717     unsigned long a, b, c, d;
0718     const u32 *pt = pc2;
0719 
0720     d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
0721     c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
0722     b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
0723     a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
0724 
0725     pe[ 0 * 2] = DES_PC2(a, b, c, d); d = rs[d];
0726     pe[ 1 * 2] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0727     pe[ 2 * 2] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0728     pe[ 3 * 2] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0729     pe[ 4 * 2] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0730     pe[ 5 * 2] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0731     pe[ 6 * 2] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0732     pe[ 7 * 2] = DES_PC2(d, a, b, c); c = rs[c];
0733     pe[ 8 * 2] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0734     pe[ 9 * 2] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0735     pe[10 * 2] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0736     pe[11 * 2] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0737     pe[12 * 2] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0738     pe[13 * 2] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0739     pe[14 * 2] = DES_PC2(c, d, a, b); b = rs[b];
0740     pe[15 * 2] = DES_PC2(b, c, d, a);
0741 
0742     /* Skip to next table set */
0743     pt += 512;
0744 
0745     d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
0746     c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
0747     b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
0748     a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
0749 
0750     pe[ 0 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d];
0751     pe[ 1 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0752     pe[ 2 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0753     pe[ 3 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0754     pe[ 4 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0755     pe[ 5 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c]; b = rs[b];
0756     pe[ 6 * 2 + 1] = DES_PC2(b, c, d, a); a = rs[a]; d = rs[d];
0757     pe[ 7 * 2 + 1] = DES_PC2(d, a, b, c); c = rs[c];
0758     pe[ 8 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0759     pe[ 9 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0760     pe[10 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0761     pe[11 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0762     pe[12 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b]; a = rs[a];
0763     pe[13 * 2 + 1] = DES_PC2(a, b, c, d); d = rs[d]; c = rs[c];
0764     pe[14 * 2 + 1] = DES_PC2(c, d, a, b); b = rs[b];
0765     pe[15 * 2 + 1] = DES_PC2(b, c, d, a);
0766 
0767     /* Fixup: 2413 5768 -> 1357 2468 */
0768     for (d = 0; d < 16; ++d) {
0769         a = pe[2 * d];
0770         b = pe[2 * d + 1];
0771         c = a ^ b;
0772         c &= 0xffff0000;
0773         a ^= c;
0774         b ^= c;
0775         ROL(b, 18);
0776         pe[2 * d] = a;
0777         pe[2 * d + 1] = b;
0778     }
0779 }
0780 
0781 static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
0782               unsigned int keylen)
0783 {
0784     struct des_ctx *dctx = crypto_tfm_ctx(tfm);
0785     u32 *flags = &tfm->crt_flags;
0786     u32 tmp[DES_EXPKEY_WORDS];
0787     int ret;
0788 
0789     /* Expand to tmp */
0790     ret = des_ekey(tmp, key);
0791 
0792     if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
0793         *flags |= CRYPTO_TFM_RES_WEAK_KEY;
0794         return -EINVAL;
0795     }
0796 
0797     /* Copy to output */
0798     memcpy(dctx->expkey, tmp, sizeof(dctx->expkey));
0799 
0800     return 0;
0801 }
0802 
0803 static void des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0804 {
0805     struct des_ctx *ctx = crypto_tfm_ctx(tfm);
0806     const u32 *K = ctx->expkey;
0807     const __le32 *s = (const __le32 *)src;
0808     __le32 *d = (__le32 *)dst;
0809     u32 L, R, A, B;
0810     int i;
0811 
0812     L = le32_to_cpu(s[0]);
0813     R = le32_to_cpu(s[1]);
0814 
0815     IP(L, R, A);
0816     for (i = 0; i < 8; i++) {
0817         ROUND(L, R, A, B, K, 2);
0818         ROUND(R, L, A, B, K, 2);
0819     }
0820     FP(R, L, A);
0821 
0822     d[0] = cpu_to_le32(R);
0823     d[1] = cpu_to_le32(L);
0824 }
0825 
0826 static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0827 {
0828     struct des_ctx *ctx = crypto_tfm_ctx(tfm);
0829     const u32 *K = ctx->expkey + DES_EXPKEY_WORDS - 2;
0830     const __le32 *s = (const __le32 *)src;
0831     __le32 *d = (__le32 *)dst;
0832     u32 L, R, A, B;
0833     int i;
0834 
0835     L = le32_to_cpu(s[0]);
0836     R = le32_to_cpu(s[1]);
0837 
0838     IP(L, R, A);
0839     for (i = 0; i < 8; i++) {
0840         ROUND(L, R, A, B, K, -2);
0841         ROUND(R, L, A, B, K, -2);
0842     }
0843     FP(R, L, A);
0844 
0845     d[0] = cpu_to_le32(R);
0846     d[1] = cpu_to_le32(L);
0847 }
0848 
0849 /*
0850  * RFC2451:
0851  *
0852  *   For DES-EDE3, there is no known need to reject weak or
0853  *   complementation keys.  Any weakness is obviated by the use of
0854  *   multiple keys.
0855  *
0856  *   However, if the first two or last two independent 64-bit keys are
0857  *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
0858  *   same as DES.  Implementers MUST reject keys that exhibit this
0859  *   property.
0860  *
0861  */
0862 int __des3_ede_setkey(u32 *expkey, u32 *flags, const u8 *key,
0863               unsigned int keylen)
0864 {
0865     const u32 *K = (const u32 *)key;
0866 
0867     if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
0868              !((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
0869              (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
0870         *flags |= CRYPTO_TFM_RES_WEAK_KEY;
0871         return -EINVAL;
0872     }
0873 
0874     des_ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
0875     dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
0876     des_ekey(expkey, key);
0877 
0878     return 0;
0879 }
0880 EXPORT_SYMBOL_GPL(__des3_ede_setkey);
0881 
0882 static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
0883                unsigned int keylen)
0884 {
0885     struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
0886     u32 *flags = &tfm->crt_flags;
0887     u32 *expkey = dctx->expkey;
0888 
0889     return __des3_ede_setkey(expkey, flags, key, keylen);
0890 }
0891 
0892 static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0893 {
0894     struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
0895     const u32 *K = dctx->expkey;
0896     const __le32 *s = (const __le32 *)src;
0897     __le32 *d = (__le32 *)dst;
0898     u32 L, R, A, B;
0899     int i;
0900 
0901     L = le32_to_cpu(s[0]);
0902     R = le32_to_cpu(s[1]);
0903 
0904     IP(L, R, A);
0905     for (i = 0; i < 8; i++) {
0906         ROUND(L, R, A, B, K, 2);
0907         ROUND(R, L, A, B, K, 2);
0908     }
0909     for (i = 0; i < 8; i++) {
0910         ROUND(R, L, A, B, K, 2);
0911         ROUND(L, R, A, B, K, 2);
0912     }
0913     for (i = 0; i < 8; i++) {
0914         ROUND(L, R, A, B, K, 2);
0915         ROUND(R, L, A, B, K, 2);
0916     }
0917     FP(R, L, A);
0918 
0919     d[0] = cpu_to_le32(R);
0920     d[1] = cpu_to_le32(L);
0921 }
0922 
0923 static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0924 {
0925     struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
0926     const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2;
0927     const __le32 *s = (const __le32 *)src;
0928     __le32 *d = (__le32 *)dst;
0929     u32 L, R, A, B;
0930     int i;
0931 
0932     L = le32_to_cpu(s[0]);
0933     R = le32_to_cpu(s[1]);
0934 
0935     IP(L, R, A);
0936     for (i = 0; i < 8; i++) {
0937         ROUND(L, R, A, B, K, -2);
0938         ROUND(R, L, A, B, K, -2);
0939     }
0940     for (i = 0; i < 8; i++) {
0941         ROUND(R, L, A, B, K, -2);
0942         ROUND(L, R, A, B, K, -2);
0943     }
0944     for (i = 0; i < 8; i++) {
0945         ROUND(L, R, A, B, K, -2);
0946         ROUND(R, L, A, B, K, -2);
0947     }
0948     FP(R, L, A);
0949 
0950     d[0] = cpu_to_le32(R);
0951     d[1] = cpu_to_le32(L);
0952 }
0953 
0954 static struct crypto_alg des_algs[2] = { {
0955     .cra_name       =   "des",
0956     .cra_driver_name    =   "des-generic",
0957     .cra_priority       =   100,
0958     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
0959     .cra_blocksize      =   DES_BLOCK_SIZE,
0960     .cra_ctxsize        =   sizeof(struct des_ctx),
0961     .cra_module     =   THIS_MODULE,
0962     .cra_alignmask      =   3,
0963     .cra_u          =   { .cipher = {
0964     .cia_min_keysize    =   DES_KEY_SIZE,
0965     .cia_max_keysize    =   DES_KEY_SIZE,
0966     .cia_setkey     =   des_setkey,
0967     .cia_encrypt        =   des_encrypt,
0968     .cia_decrypt        =   des_decrypt } }
0969 }, {
0970     .cra_name       =   "des3_ede",
0971     .cra_driver_name    =   "des3_ede-generic",
0972     .cra_priority       =   100,
0973     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
0974     .cra_blocksize      =   DES3_EDE_BLOCK_SIZE,
0975     .cra_ctxsize        =   sizeof(struct des3_ede_ctx),
0976     .cra_module     =   THIS_MODULE,
0977     .cra_alignmask      =   3,
0978     .cra_u          =   { .cipher = {
0979     .cia_min_keysize    =   DES3_EDE_KEY_SIZE,
0980     .cia_max_keysize    =   DES3_EDE_KEY_SIZE,
0981     .cia_setkey     =   des3_ede_setkey,
0982     .cia_encrypt        =   des3_ede_encrypt,
0983     .cia_decrypt        =   des3_ede_decrypt } }
0984 } };
0985 
0986 static int __init des_generic_mod_init(void)
0987 {
0988     return crypto_register_algs(des_algs, ARRAY_SIZE(des_algs));
0989 }
0990 
0991 static void __exit des_generic_mod_fini(void)
0992 {
0993     crypto_unregister_algs(des_algs, ARRAY_SIZE(des_algs));
0994 }
0995 
0996 module_init(des_generic_mod_init);
0997 module_exit(des_generic_mod_fini);
0998 
0999 MODULE_LICENSE("GPL");
1000 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
1001 MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>");
1002 MODULE_ALIAS_CRYPTO("des");
1003 MODULE_ALIAS_CRYPTO("des-generic");
1004 MODULE_ALIAS_CRYPTO("des3_ede");
1005 MODULE_ALIAS_CRYPTO("des3_ede-generic");