Back to home page

OSCL-LXR

 
 

    


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