0001
0002
0003
0004
0005
0006
0007
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
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
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
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
0597
0598
0599
0600
0601
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
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623 static unsigned long des_ekey(u32 *pe, const u8 *k)
0624 {
0625
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
0652 w = (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
0653
0654
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
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
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
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
0710
0711
0712
0713
0714 static void dkey(u32 *pe, const u8 *k)
0715 {
0716
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
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
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");