1*f0865ec9SKyle Evans /* 2*f0865ec9SKyle Evans * Copyright (C) 2021 - This file is part of libecc project 3*f0865ec9SKyle Evans * 4*f0865ec9SKyle Evans * Authors: 5*f0865ec9SKyle Evans * Ryad BENADJILA <ryadbenadjila@gmail.com> 6*f0865ec9SKyle Evans * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7*f0865ec9SKyle Evans * 8*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license. 9*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project. 10*f0865ec9SKyle Evans */ 11*f0865ec9SKyle Evans 12*f0865ec9SKyle Evans #include "tdes.h" 13*f0865ec9SKyle Evans 14*f0865ec9SKyle Evans /* This is a very straightforward and basic implementation of DES and T-DES */ 15*f0865ec9SKyle Evans 16*f0865ec9SKyle Evans /* platform-independant 32-bit integer manipulation macros */ 17*f0865ec9SKyle Evans #ifndef GET_UINT32 18*f0865ec9SKyle Evans #define GET_UINT32(n,b,i) \ 19*f0865ec9SKyle Evans do { \ 20*f0865ec9SKyle Evans (n) = ( (u32) (b)[(i) ] << 24 ) \ 21*f0865ec9SKyle Evans | ( (u32) (b)[(i) + 1] << 16 ) \ 22*f0865ec9SKyle Evans | ( (u32) (b)[(i) + 2] << 8 ) \ 23*f0865ec9SKyle Evans | ( (u32) (b)[(i) + 3] ); \ 24*f0865ec9SKyle Evans } while( 0 ) 25*f0865ec9SKyle Evans #endif 26*f0865ec9SKyle Evans 27*f0865ec9SKyle Evans #ifndef PUT_UINT32 28*f0865ec9SKyle Evans #define PUT_UINT32(n,b,i) \ 29*f0865ec9SKyle Evans do { \ 30*f0865ec9SKyle Evans (b)[(i) ] = (u8) ( (n) >> 24 ); \ 31*f0865ec9SKyle Evans (b)[(i) + 1] = (u8) ( (n) >> 16 ); \ 32*f0865ec9SKyle Evans (b)[(i) + 2] = (u8) ( (n) >> 8 ); \ 33*f0865ec9SKyle Evans (b)[(i) + 3] = (u8) ( (n) ); \ 34*f0865ec9SKyle Evans } while( 0 ) 35*f0865ec9SKyle Evans #endif 36*f0865ec9SKyle Evans 37*f0865ec9SKyle Evans /* DES 8 S-Boxes */ 38*f0865ec9SKyle Evans static const u32 SB[8][64] = { 39*f0865ec9SKyle Evans { 40*f0865ec9SKyle Evans 0x01010400, 0x00000000, 0x00010000, 0x01010404, 41*f0865ec9SKyle Evans 0x01010004, 0x00010404, 0x00000004, 0x00010000, 42*f0865ec9SKyle Evans 0x00000400, 0x01010400, 0x01010404, 0x00000400, 43*f0865ec9SKyle Evans 0x01000404, 0x01010004, 0x01000000, 0x00000004, 44*f0865ec9SKyle Evans 0x00000404, 0x01000400, 0x01000400, 0x00010400, 45*f0865ec9SKyle Evans 0x00010400, 0x01010000, 0x01010000, 0x01000404, 46*f0865ec9SKyle Evans 0x00010004, 0x01000004, 0x01000004, 0x00010004, 47*f0865ec9SKyle Evans 0x00000000, 0x00000404, 0x00010404, 0x01000000, 48*f0865ec9SKyle Evans 0x00010000, 0x01010404, 0x00000004, 0x01010000, 49*f0865ec9SKyle Evans 0x01010400, 0x01000000, 0x01000000, 0x00000400, 50*f0865ec9SKyle Evans 0x01010004, 0x00010000, 0x00010400, 0x01000004, 51*f0865ec9SKyle Evans 0x00000400, 0x00000004, 0x01000404, 0x00010404, 52*f0865ec9SKyle Evans 0x01010404, 0x00010004, 0x01010000, 0x01000404, 53*f0865ec9SKyle Evans 0x01000004, 0x00000404, 0x00010404, 0x01010400, 54*f0865ec9SKyle Evans 0x00000404, 0x01000400, 0x01000400, 0x00000000, 55*f0865ec9SKyle Evans 0x00010004, 0x00010400, 0x00000000, 0x01010004 56*f0865ec9SKyle Evans }, 57*f0865ec9SKyle Evans { 58*f0865ec9SKyle Evans 0x80108020, 0x80008000, 0x00008000, 0x00108020, 59*f0865ec9SKyle Evans 0x00100000, 0x00000020, 0x80100020, 0x80008020, 60*f0865ec9SKyle Evans 0x80000020, 0x80108020, 0x80108000, 0x80000000, 61*f0865ec9SKyle Evans 0x80008000, 0x00100000, 0x00000020, 0x80100020, 62*f0865ec9SKyle Evans 0x00108000, 0x00100020, 0x80008020, 0x00000000, 63*f0865ec9SKyle Evans 0x80000000, 0x00008000, 0x00108020, 0x80100000, 64*f0865ec9SKyle Evans 0x00100020, 0x80000020, 0x00000000, 0x00108000, 65*f0865ec9SKyle Evans 0x00008020, 0x80108000, 0x80100000, 0x00008020, 66*f0865ec9SKyle Evans 0x00000000, 0x00108020, 0x80100020, 0x00100000, 67*f0865ec9SKyle Evans 0x80008020, 0x80100000, 0x80108000, 0x00008000, 68*f0865ec9SKyle Evans 0x80100000, 0x80008000, 0x00000020, 0x80108020, 69*f0865ec9SKyle Evans 0x00108020, 0x00000020, 0x00008000, 0x80000000, 70*f0865ec9SKyle Evans 0x00008020, 0x80108000, 0x00100000, 0x80000020, 71*f0865ec9SKyle Evans 0x00100020, 0x80008020, 0x80000020, 0x00100020, 72*f0865ec9SKyle Evans 0x00108000, 0x00000000, 0x80008000, 0x00008020, 73*f0865ec9SKyle Evans 0x80000000, 0x80100020, 0x80108020, 0x00108000 74*f0865ec9SKyle Evans }, 75*f0865ec9SKyle Evans { 76*f0865ec9SKyle Evans 0x00000208, 0x08020200, 0x00000000, 0x08020008, 77*f0865ec9SKyle Evans 0x08000200, 0x00000000, 0x00020208, 0x08000200, 78*f0865ec9SKyle Evans 0x00020008, 0x08000008, 0x08000008, 0x00020000, 79*f0865ec9SKyle Evans 0x08020208, 0x00020008, 0x08020000, 0x00000208, 80*f0865ec9SKyle Evans 0x08000000, 0x00000008, 0x08020200, 0x00000200, 81*f0865ec9SKyle Evans 0x00020200, 0x08020000, 0x08020008, 0x00020208, 82*f0865ec9SKyle Evans 0x08000208, 0x00020200, 0x00020000, 0x08000208, 83*f0865ec9SKyle Evans 0x00000008, 0x08020208, 0x00000200, 0x08000000, 84*f0865ec9SKyle Evans 0x08020200, 0x08000000, 0x00020008, 0x00000208, 85*f0865ec9SKyle Evans 0x00020000, 0x08020200, 0x08000200, 0x00000000, 86*f0865ec9SKyle Evans 0x00000200, 0x00020008, 0x08020208, 0x08000200, 87*f0865ec9SKyle Evans 0x08000008, 0x00000200, 0x00000000, 0x08020008, 88*f0865ec9SKyle Evans 0x08000208, 0x00020000, 0x08000000, 0x08020208, 89*f0865ec9SKyle Evans 0x00000008, 0x00020208, 0x00020200, 0x08000008, 90*f0865ec9SKyle Evans 0x08020000, 0x08000208, 0x00000208, 0x08020000, 91*f0865ec9SKyle Evans 0x00020208, 0x00000008, 0x08020008, 0x00020200 92*f0865ec9SKyle Evans }, 93*f0865ec9SKyle Evans { 94*f0865ec9SKyle Evans 0x00802001, 0x00002081, 0x00002081, 0x00000080, 95*f0865ec9SKyle Evans 0x00802080, 0x00800081, 0x00800001, 0x00002001, 96*f0865ec9SKyle Evans 0x00000000, 0x00802000, 0x00802000, 0x00802081, 97*f0865ec9SKyle Evans 0x00000081, 0x00000000, 0x00800080, 0x00800001, 98*f0865ec9SKyle Evans 0x00000001, 0x00002000, 0x00800000, 0x00802001, 99*f0865ec9SKyle Evans 0x00000080, 0x00800000, 0x00002001, 0x00002080, 100*f0865ec9SKyle Evans 0x00800081, 0x00000001, 0x00002080, 0x00800080, 101*f0865ec9SKyle Evans 0x00002000, 0x00802080, 0x00802081, 0x00000081, 102*f0865ec9SKyle Evans 0x00800080, 0x00800001, 0x00802000, 0x00802081, 103*f0865ec9SKyle Evans 0x00000081, 0x00000000, 0x00000000, 0x00802000, 104*f0865ec9SKyle Evans 0x00002080, 0x00800080, 0x00800081, 0x00000001, 105*f0865ec9SKyle Evans 0x00802001, 0x00002081, 0x00002081, 0x00000080, 106*f0865ec9SKyle Evans 0x00802081, 0x00000081, 0x00000001, 0x00002000, 107*f0865ec9SKyle Evans 0x00800001, 0x00002001, 0x00802080, 0x00800081, 108*f0865ec9SKyle Evans 0x00002001, 0x00002080, 0x00800000, 0x00802001, 109*f0865ec9SKyle Evans 0x00000080, 0x00800000, 0x00002000, 0x00802080 110*f0865ec9SKyle Evans }, 111*f0865ec9SKyle Evans { 112*f0865ec9SKyle Evans 0x00000100, 0x02080100, 0x02080000, 0x42000100, 113*f0865ec9SKyle Evans 0x00080000, 0x00000100, 0x40000000, 0x02080000, 114*f0865ec9SKyle Evans 0x40080100, 0x00080000, 0x02000100, 0x40080100, 115*f0865ec9SKyle Evans 0x42000100, 0x42080000, 0x00080100, 0x40000000, 116*f0865ec9SKyle Evans 0x02000000, 0x40080000, 0x40080000, 0x00000000, 117*f0865ec9SKyle Evans 0x40000100, 0x42080100, 0x42080100, 0x02000100, 118*f0865ec9SKyle Evans 0x42080000, 0x40000100, 0x00000000, 0x42000000, 119*f0865ec9SKyle Evans 0x02080100, 0x02000000, 0x42000000, 0x00080100, 120*f0865ec9SKyle Evans 0x00080000, 0x42000100, 0x00000100, 0x02000000, 121*f0865ec9SKyle Evans 0x40000000, 0x02080000, 0x42000100, 0x40080100, 122*f0865ec9SKyle Evans 0x02000100, 0x40000000, 0x42080000, 0x02080100, 123*f0865ec9SKyle Evans 0x40080100, 0x00000100, 0x02000000, 0x42080000, 124*f0865ec9SKyle Evans 0x42080100, 0x00080100, 0x42000000, 0x42080100, 125*f0865ec9SKyle Evans 0x02080000, 0x00000000, 0x40080000, 0x42000000, 126*f0865ec9SKyle Evans 0x00080100, 0x02000100, 0x40000100, 0x00080000, 127*f0865ec9SKyle Evans 0x00000000, 0x40080000, 0x02080100, 0x40000100 128*f0865ec9SKyle Evans }, 129*f0865ec9SKyle Evans { 130*f0865ec9SKyle Evans 0x20000010, 0x20400000, 0x00004000, 0x20404010, 131*f0865ec9SKyle Evans 0x20400000, 0x00000010, 0x20404010, 0x00400000, 132*f0865ec9SKyle Evans 0x20004000, 0x00404010, 0x00400000, 0x20000010, 133*f0865ec9SKyle Evans 0x00400010, 0x20004000, 0x20000000, 0x00004010, 134*f0865ec9SKyle Evans 0x00000000, 0x00400010, 0x20004010, 0x00004000, 135*f0865ec9SKyle Evans 0x00404000, 0x20004010, 0x00000010, 0x20400010, 136*f0865ec9SKyle Evans 0x20400010, 0x00000000, 0x00404010, 0x20404000, 137*f0865ec9SKyle Evans 0x00004010, 0x00404000, 0x20404000, 0x20000000, 138*f0865ec9SKyle Evans 0x20004000, 0x00000010, 0x20400010, 0x00404000, 139*f0865ec9SKyle Evans 0x20404010, 0x00400000, 0x00004010, 0x20000010, 140*f0865ec9SKyle Evans 0x00400000, 0x20004000, 0x20000000, 0x00004010, 141*f0865ec9SKyle Evans 0x20000010, 0x20404010, 0x00404000, 0x20400000, 142*f0865ec9SKyle Evans 0x00404010, 0x20404000, 0x00000000, 0x20400010, 143*f0865ec9SKyle Evans 0x00000010, 0x00004000, 0x20400000, 0x00404010, 144*f0865ec9SKyle Evans 0x00004000, 0x00400010, 0x20004010, 0x00000000, 145*f0865ec9SKyle Evans 0x20404000, 0x20000000, 0x00400010, 0x20004010 146*f0865ec9SKyle Evans }, 147*f0865ec9SKyle Evans { 148*f0865ec9SKyle Evans 0x00200000, 0x04200002, 0x04000802, 0x00000000, 149*f0865ec9SKyle Evans 0x00000800, 0x04000802, 0x00200802, 0x04200800, 150*f0865ec9SKyle Evans 0x04200802, 0x00200000, 0x00000000, 0x04000002, 151*f0865ec9SKyle Evans 0x00000002, 0x04000000, 0x04200002, 0x00000802, 152*f0865ec9SKyle Evans 0x04000800, 0x00200802, 0x00200002, 0x04000800, 153*f0865ec9SKyle Evans 0x04000002, 0x04200000, 0x04200800, 0x00200002, 154*f0865ec9SKyle Evans 0x04200000, 0x00000800, 0x00000802, 0x04200802, 155*f0865ec9SKyle Evans 0x00200800, 0x00000002, 0x04000000, 0x00200800, 156*f0865ec9SKyle Evans 0x04000000, 0x00200800, 0x00200000, 0x04000802, 157*f0865ec9SKyle Evans 0x04000802, 0x04200002, 0x04200002, 0x00000002, 158*f0865ec9SKyle Evans 0x00200002, 0x04000000, 0x04000800, 0x00200000, 159*f0865ec9SKyle Evans 0x04200800, 0x00000802, 0x00200802, 0x04200800, 160*f0865ec9SKyle Evans 0x00000802, 0x04000002, 0x04200802, 0x04200000, 161*f0865ec9SKyle Evans 0x00200800, 0x00000000, 0x00000002, 0x04200802, 162*f0865ec9SKyle Evans 0x00000000, 0x00200802, 0x04200000, 0x00000800, 163*f0865ec9SKyle Evans 0x04000002, 0x04000800, 0x00000800, 0x00200002 164*f0865ec9SKyle Evans }, 165*f0865ec9SKyle Evans { 166*f0865ec9SKyle Evans 0x10001040, 0x00001000, 0x00040000, 0x10041040, 167*f0865ec9SKyle Evans 0x10000000, 0x10001040, 0x00000040, 0x10000000, 168*f0865ec9SKyle Evans 0x00040040, 0x10040000, 0x10041040, 0x00041000, 169*f0865ec9SKyle Evans 0x10041000, 0x00041040, 0x00001000, 0x00000040, 170*f0865ec9SKyle Evans 0x10040000, 0x10000040, 0x10001000, 0x00001040, 171*f0865ec9SKyle Evans 0x00041000, 0x00040040, 0x10040040, 0x10041000, 172*f0865ec9SKyle Evans 0x00001040, 0x00000000, 0x00000000, 0x10040040, 173*f0865ec9SKyle Evans 0x10000040, 0x10001000, 0x00041040, 0x00040000, 174*f0865ec9SKyle Evans 0x00041040, 0x00040000, 0x10041000, 0x00001000, 175*f0865ec9SKyle Evans 0x00000040, 0x10040040, 0x00001000, 0x00041040, 176*f0865ec9SKyle Evans 0x10001000, 0x00000040, 0x10000040, 0x10040000, 177*f0865ec9SKyle Evans 0x10040040, 0x10000000, 0x00040000, 0x10001040, 178*f0865ec9SKyle Evans 0x00000000, 0x10041040, 0x00040040, 0x10000040, 179*f0865ec9SKyle Evans 0x10040000, 0x10001000, 0x10001040, 0x00000000, 180*f0865ec9SKyle Evans 0x10041040, 0x00041000, 0x00041000, 0x00001040, 181*f0865ec9SKyle Evans 0x00001040, 0x00040040, 0x10000000, 0x10041000 182*f0865ec9SKyle Evans } 183*f0865ec9SKyle Evans }; 184*f0865ec9SKyle Evans 185*f0865ec9SKyle Evans /* PC1: left and right halves bit-swap */ 186*f0865ec9SKyle Evans 187*f0865ec9SKyle Evans static const u32 LH[16] = 188*f0865ec9SKyle Evans { 189*f0865ec9SKyle Evans 0x00000000, 0x00000001, 0x00000100, 0x00000101, 190*f0865ec9SKyle Evans 0x00010000, 0x00010001, 0x00010100, 0x00010101, 191*f0865ec9SKyle Evans 0x01000000, 0x01000001, 0x01000100, 0x01000101, 192*f0865ec9SKyle Evans 0x01010000, 0x01010001, 0x01010100, 0x01010101 193*f0865ec9SKyle Evans }; 194*f0865ec9SKyle Evans 195*f0865ec9SKyle Evans static const u32 RH[16] = 196*f0865ec9SKyle Evans { 197*f0865ec9SKyle Evans 0x00000000, 0x01000000, 0x00010000, 0x01010000, 198*f0865ec9SKyle Evans 0x00000100, 0x01000100, 0x00010100, 0x01010100, 199*f0865ec9SKyle Evans 0x00000001, 0x01000001, 0x00010001, 0x01010001, 200*f0865ec9SKyle Evans 0x00000101, 0x01000101, 0x00010101, 0x01010101, 201*f0865ec9SKyle Evans }; 202*f0865ec9SKyle Evans 203*f0865ec9SKyle Evans /* DES Initial Permutation (IP) */ 204*f0865ec9SKyle Evans static inline void des_ip(u32 L[1], u32 R[1]) 205*f0865ec9SKyle Evans { 206*f0865ec9SKyle Evans u32 T; 207*f0865ec9SKyle Evans 208*f0865ec9SKyle Evans T = ((L[0] >> 4) ^ R[0]) & 0x0F0F0F0F; R[0] ^= T; L[0] ^= (T << 4); 209*f0865ec9SKyle Evans T = ((L[0] >> 16) ^ R[0]) & 0x0000FFFF; R[0] ^= T; L[0] ^= (T << 16); 210*f0865ec9SKyle Evans T = ((R[0] >> 2) ^ L[0]) & 0x33333333; L[0] ^= T; R[0] ^= (T << 2); 211*f0865ec9SKyle Evans T = ((R[0] >> 8) ^ L[0]) & 0x00FF00FF; L[0] ^= T; R[0] ^= (T << 8); 212*f0865ec9SKyle Evans R[0] = ((R[0] << 1) | (R[0] >> 31)) & 0xFFFFFFFF; 213*f0865ec9SKyle Evans T = (L[0] ^ R[0]) & 0xAAAAAAAA; R[0] ^= T; L[0] ^= T; 214*f0865ec9SKyle Evans L[0] = ((L[0] << 1) | (L[0] >> 31)) & 0xFFFFFFFF; 215*f0865ec9SKyle Evans 216*f0865ec9SKyle Evans return; 217*f0865ec9SKyle Evans } 218*f0865ec9SKyle Evans 219*f0865ec9SKyle Evans /* DES Final Permutation (FP) */ 220*f0865ec9SKyle Evans static inline void des_fp(u32 L[1], u32 R[1]) 221*f0865ec9SKyle Evans { 222*f0865ec9SKyle Evans u32 T; 223*f0865ec9SKyle Evans 224*f0865ec9SKyle Evans L[0] = ((L[0] << 31) | (L[0] >> 1)) & 0xFFFFFFFF; 225*f0865ec9SKyle Evans T = (L[0] ^ R[0]) & 0xAAAAAAAA; L[0] ^= T; R[0] ^= T; 226*f0865ec9SKyle Evans R[0] = ((R[0] << 31) | (R[0] >> 1)) & 0xFFFFFFFF; 227*f0865ec9SKyle Evans T = ((R[0] >> 8) ^ L[0]) & 0x00FF00FF; L[0] ^= T; R[0] ^= (T << 8); 228*f0865ec9SKyle Evans T = ((R[0] >> 2) ^ L[0]) & 0x33333333; L[0] ^= T; R[0] ^= (T << 2); 229*f0865ec9SKyle Evans T = ((L[0] >> 16) ^ R[0]) & 0x0000FFFF; R[0] ^= T; L[0] ^= (T << 16); 230*f0865ec9SKyle Evans T = ((L[0] >> 4) ^ R[0]) & 0x0F0F0F0F; R[0] ^= T; L[0] ^= (T << 4); 231*f0865ec9SKyle Evans 232*f0865ec9SKyle Evans return; 233*f0865ec9SKyle Evans } 234*f0865ec9SKyle Evans 235*f0865ec9SKyle Evans /* DES function: F(R, K) + L with inversion */ 236*f0865ec9SKyle Evans static inline void des_round(u32 L[1], u32 R[1], u64 K) 237*f0865ec9SKyle Evans { 238*f0865ec9SKyle Evans u32 T; 239*f0865ec9SKyle Evans u32 k1, k2; 240*f0865ec9SKyle Evans 241*f0865ec9SKyle Evans k1 = (u32)K; 242*f0865ec9SKyle Evans k2 = (u32)(K >> 32); 243*f0865ec9SKyle Evans 244*f0865ec9SKyle Evans T = k1 ^ L[0]; 245*f0865ec9SKyle Evans R[0] ^= SB[7][ (T) & 0x3f] ^ SB[5][ (T >> 8) & 0x3f] ^ SB[3][ (T >> 16) & 0x3f] ^ SB[1][ (T >> 24) & 0x3f]; 246*f0865ec9SKyle Evans T = k2 ^ ((L[0] << 28) | (L[0] >> 4)); 247*f0865ec9SKyle Evans R[0] ^= SB[6][ (T) & 0x3f] ^ SB[4][ (T >> 8) & 0x3f] ^ SB[2][ (T >> 16) & 0x3f] ^ SB[0][ (T >> 24) & 0x3f]; 248*f0865ec9SKyle Evans 249*f0865ec9SKyle Evans return; 250*f0865ec9SKyle Evans } 251*f0865ec9SKyle Evans 252*f0865ec9SKyle Evans /* DES key schedule */ 253*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int des_set_key(des_context *ctx, const u8 k[8], des_direction dir) 254*f0865ec9SKyle Evans { 255*f0865ec9SKyle Evans u32 i; 256*f0865ec9SKyle Evans u32 C, D, T; 257*f0865ec9SKyle Evans int ret; 258*f0865ec9SKyle Evans 259*f0865ec9SKyle Evans if((ctx == NULL) || (k == NULL)){ 260*f0865ec9SKyle Evans ret = -1; 261*f0865ec9SKyle Evans goto err; 262*f0865ec9SKyle Evans } 263*f0865ec9SKyle Evans 264*f0865ec9SKyle Evans ctx->dir = dir; 265*f0865ec9SKyle Evans 266*f0865ec9SKyle Evans GET_UINT32(C, k, 0); 267*f0865ec9SKyle Evans GET_UINT32(D, k, 4); 268*f0865ec9SKyle Evans 269*f0865ec9SKyle Evans /* Permuted choice 1 */ 270*f0865ec9SKyle Evans T = ((D >> 4) ^ C) & 0x0F0F0F0F; C ^= T; D ^= (T << 4); 271*f0865ec9SKyle Evans T = ((D ) ^ C) & 0x10101010; C ^= T; D ^= (T ); 272*f0865ec9SKyle Evans 273*f0865ec9SKyle Evans C = (LH[ (C ) & 0xF] << 3) | (LH[ (C >> 8) & 0xF ] << 2) 274*f0865ec9SKyle Evans | (LH[ (C >> 16) & 0xF] << 1) | (LH[ (C >> 24) & 0xF ] ) 275*f0865ec9SKyle Evans | (LH[ (C >> 5) & 0xF] << 7) | (LH[ (C >> 13) & 0xF ] << 6) 276*f0865ec9SKyle Evans | (LH[ (C >> 21) & 0xF] << 5) | (LH[ (C >> 29) & 0xF ] << 4); 277*f0865ec9SKyle Evans 278*f0865ec9SKyle Evans D = (RH[ (D >> 1) & 0xF] << 3) | (RH[ (D >> 9) & 0xF ] << 2) 279*f0865ec9SKyle Evans | (RH[ (D >> 17) & 0xF] << 1) | (RH[ (D >> 25) & 0xF ] ) 280*f0865ec9SKyle Evans | (RH[ (D >> 4) & 0xF] << 7) | (RH[ (D >> 12) & 0xF ] << 6) 281*f0865ec9SKyle Evans | (RH[ (D >> 20) & 0xF] << 5) | (RH[ (D >> 28) & 0xF ] << 4); 282*f0865ec9SKyle Evans 283*f0865ec9SKyle Evans C &= 0x0FFFFFFF; 284*f0865ec9SKyle Evans D &= 0x0FFFFFFF; 285*f0865ec9SKyle Evans 286*f0865ec9SKyle Evans /* Compute the subkeys */ 287*f0865ec9SKyle Evans for( i = 0; i < 16; i++ ){ 288*f0865ec9SKyle Evans u32 k1, k2; 289*f0865ec9SKyle Evans if((i < 2) || (i == 8) || (i == 15)){ 290*f0865ec9SKyle Evans C = ((C << 1) | (C >> 27)) & 0x0FFFFFFF; 291*f0865ec9SKyle Evans D = ((D << 1) | (D >> 27)) & 0x0FFFFFFF; 292*f0865ec9SKyle Evans } 293*f0865ec9SKyle Evans else{ 294*f0865ec9SKyle Evans C = ((C << 2) | (C >> 26)) & 0x0FFFFFFF; 295*f0865ec9SKyle Evans D = ((D << 2) | (D >> 26)) & 0x0FFFFFFF; 296*f0865ec9SKyle Evans } 297*f0865ec9SKyle Evans 298*f0865ec9SKyle Evans k1 = ((C << 4) & 0x24000000) | ((C << 28) & 0x10000000) 299*f0865ec9SKyle Evans | ((C << 14) & 0x08000000) | ((C << 18) & 0x02080000) 300*f0865ec9SKyle Evans | ((C << 6) & 0x01000000) | ((C << 9) & 0x00200000) 301*f0865ec9SKyle Evans | ((C >> 1) & 0x00100000) | ((C << 10) & 0x00040000) 302*f0865ec9SKyle Evans | ((C << 2) & 0x00020000) | ((C >> 10) & 0x00010000) 303*f0865ec9SKyle Evans | ((D >> 13) & 0x00002000) | ((D >> 4) & 0x00001000) 304*f0865ec9SKyle Evans | ((D << 6) & 0x00000800) | ((D >> 1) & 0x00000400) 305*f0865ec9SKyle Evans | ((D >> 14) & 0x00000200) | ((D ) & 0x00000100) 306*f0865ec9SKyle Evans | ((D >> 5) & 0x00000020) | ((D >> 10) & 0x00000010) 307*f0865ec9SKyle Evans | ((D >> 3) & 0x00000008) | ((D >> 18) & 0x00000004) 308*f0865ec9SKyle Evans | ((D >> 26) & 0x00000002) | ((D >> 24) & 0x00000001); 309*f0865ec9SKyle Evans 310*f0865ec9SKyle Evans k2 = ((C << 15) & 0x20000000) | ((C << 17) & 0x10000000) 311*f0865ec9SKyle Evans | ((C << 10) & 0x08000000) | ((C << 22) & 0x04000000) 312*f0865ec9SKyle Evans | ((C >> 2) & 0x02000000) | ((C << 1) & 0x01000000) 313*f0865ec9SKyle Evans | ((C << 16) & 0x00200000) | ((C << 11) & 0x00100000) 314*f0865ec9SKyle Evans | ((C << 3) & 0x00080000) | ((C >> 6) & 0x00040000) 315*f0865ec9SKyle Evans | ((C << 15) & 0x00020000) | ((C >> 4) & 0x00010000) 316*f0865ec9SKyle Evans | ((D >> 2) & 0x00002000) | ((D << 8) & 0x00001000) 317*f0865ec9SKyle Evans | ((D >> 14) & 0x00000808) | ((D >> 9) & 0x00000400) 318*f0865ec9SKyle Evans | ((D ) & 0x00000200) | ((D << 7) & 0x00000100) 319*f0865ec9SKyle Evans | ((D >> 7) & 0x00000020) | ((D >> 3) & 0x00000011) 320*f0865ec9SKyle Evans | ((D << 2) & 0x00000004) | ((D >> 21) & 0x00000002); 321*f0865ec9SKyle Evans 322*f0865ec9SKyle Evans if(dir == DES_ENCRYPTION){ 323*f0865ec9SKyle Evans ctx->sk[i] = (((u64)k2) << 32) | (u64)k1; 324*f0865ec9SKyle Evans } 325*f0865ec9SKyle Evans else if(dir == DES_DECRYPTION){ 326*f0865ec9SKyle Evans ctx->sk[15-i] = (((u64)k2) << 32) | (u64)k1; 327*f0865ec9SKyle Evans } 328*f0865ec9SKyle Evans else{ 329*f0865ec9SKyle Evans ret = -1; 330*f0865ec9SKyle Evans goto err; 331*f0865ec9SKyle Evans } 332*f0865ec9SKyle Evans } 333*f0865ec9SKyle Evans 334*f0865ec9SKyle Evans ret = 0; 335*f0865ec9SKyle Evans 336*f0865ec9SKyle Evans err: 337*f0865ec9SKyle Evans return ret; 338*f0865ec9SKyle Evans } 339*f0865ec9SKyle Evans 340*f0865ec9SKyle Evans /* DES encryption core */ 341*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static inline int des_core(const des_context *ctx, const u8 input[8], u8 output[8]) 342*f0865ec9SKyle Evans { 343*f0865ec9SKyle Evans u32 L, R; 344*f0865ec9SKyle Evans u32 i; 345*f0865ec9SKyle Evans int ret; 346*f0865ec9SKyle Evans 347*f0865ec9SKyle Evans if((ctx == NULL) || (input == NULL) || (output == NULL)){ 348*f0865ec9SKyle Evans ret = -1; 349*f0865ec9SKyle Evans goto err; 350*f0865ec9SKyle Evans } 351*f0865ec9SKyle Evans 352*f0865ec9SKyle Evans GET_UINT32(L, input, 0); 353*f0865ec9SKyle Evans GET_UINT32(R, input, 4); 354*f0865ec9SKyle Evans 355*f0865ec9SKyle Evans des_ip(&L, &R); 356*f0865ec9SKyle Evans 357*f0865ec9SKyle Evans for(i = 0; i < 16; i++){ 358*f0865ec9SKyle Evans if((i % 2) == 0){ 359*f0865ec9SKyle Evans des_round(&R, &L, ctx->sk[i]); 360*f0865ec9SKyle Evans } 361*f0865ec9SKyle Evans else{ 362*f0865ec9SKyle Evans des_round(&L, &R, ctx->sk[i]); 363*f0865ec9SKyle Evans } 364*f0865ec9SKyle Evans } 365*f0865ec9SKyle Evans 366*f0865ec9SKyle Evans des_fp(&R, &L); 367*f0865ec9SKyle Evans 368*f0865ec9SKyle Evans PUT_UINT32(R, output, 0); 369*f0865ec9SKyle Evans PUT_UINT32(L, output, 4); 370*f0865ec9SKyle Evans 371*f0865ec9SKyle Evans ret = 0; 372*f0865ec9SKyle Evans err: 373*f0865ec9SKyle Evans return ret; 374*f0865ec9SKyle Evans } 375*f0865ec9SKyle Evans 376*f0865ec9SKyle Evans /* DES encryption/decryption */ 377*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int des(const des_context *ctx, const u8 input[8], u8 output[8]) 378*f0865ec9SKyle Evans { 379*f0865ec9SKyle Evans return des_core(ctx, input, output); 380*f0865ec9SKyle Evans } 381*f0865ec9SKyle Evans 382*f0865ec9SKyle Evans /* TDES key schedules */ 383*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int des3_set_keys(des3_context *ctx, const u8 k1[8], const u8 k2[8], const u8 k3[8], des_direction dir) 384*f0865ec9SKyle Evans { 385*f0865ec9SKyle Evans int ret; 386*f0865ec9SKyle Evans 387*f0865ec9SKyle Evans if((ctx == NULL) || (k1 == NULL) || (k2 == NULL)){ 388*f0865ec9SKyle Evans ret = -1; 389*f0865ec9SKyle Evans goto err; 390*f0865ec9SKyle Evans } 391*f0865ec9SKyle Evans ctx->dir = dir; 392*f0865ec9SKyle Evans if(dir == DES_ENCRYPTION){ 393*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[0]), k1, DES_ENCRYPTION)){ 394*f0865ec9SKyle Evans ret = -1; 395*f0865ec9SKyle Evans goto err; 396*f0865ec9SKyle Evans } 397*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[1]), k2, DES_DECRYPTION)){ 398*f0865ec9SKyle Evans ret = -1; 399*f0865ec9SKyle Evans goto err; 400*f0865ec9SKyle Evans } 401*f0865ec9SKyle Evans if(k3 == NULL){ 402*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[2]), k1, DES_ENCRYPTION)){ 403*f0865ec9SKyle Evans ret = -1; 404*f0865ec9SKyle Evans goto err; 405*f0865ec9SKyle Evans } 406*f0865ec9SKyle Evans } 407*f0865ec9SKyle Evans else{ 408*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[2]), k3, DES_ENCRYPTION)){ 409*f0865ec9SKyle Evans ret = -1; 410*f0865ec9SKyle Evans goto err; 411*f0865ec9SKyle Evans } 412*f0865ec9SKyle Evans } 413*f0865ec9SKyle Evans } 414*f0865ec9SKyle Evans else if(dir == DES_DECRYPTION){ 415*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[0]), k1, DES_DECRYPTION)){ 416*f0865ec9SKyle Evans ret = -1; 417*f0865ec9SKyle Evans goto err; 418*f0865ec9SKyle Evans } 419*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[1]), k2, DES_ENCRYPTION)){ 420*f0865ec9SKyle Evans ret = -1; 421*f0865ec9SKyle Evans goto err; 422*f0865ec9SKyle Evans } 423*f0865ec9SKyle Evans if(k3 == NULL){ 424*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[2]), k1, DES_DECRYPTION)){ 425*f0865ec9SKyle Evans ret = -1; 426*f0865ec9SKyle Evans goto err; 427*f0865ec9SKyle Evans } 428*f0865ec9SKyle Evans } 429*f0865ec9SKyle Evans else{ 430*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[2]), k3, DES_DECRYPTION)){ 431*f0865ec9SKyle Evans ret = -1; 432*f0865ec9SKyle Evans goto err; 433*f0865ec9SKyle Evans } 434*f0865ec9SKyle Evans } 435*f0865ec9SKyle Evans } 436*f0865ec9SKyle Evans else{ 437*f0865ec9SKyle Evans ret = -1; 438*f0865ec9SKyle Evans goto err; 439*f0865ec9SKyle Evans } 440*f0865ec9SKyle Evans 441*f0865ec9SKyle Evans ret = 0; 442*f0865ec9SKyle Evans err: 443*f0865ec9SKyle Evans return ret; 444*f0865ec9SKyle Evans } 445*f0865ec9SKyle Evans 446*f0865ec9SKyle Evans /* TDES encryption/decryption */ 447*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int des3(const des3_context *ctx, const u8 input[8], u8 output[8]) 448*f0865ec9SKyle Evans { 449*f0865ec9SKyle Evans int ret; 450*f0865ec9SKyle Evans u8 tmp[8]; 451*f0865ec9SKyle Evans 452*f0865ec9SKyle Evans if(ctx == NULL){ 453*f0865ec9SKyle Evans ret = -1; 454*f0865ec9SKyle Evans goto err; 455*f0865ec9SKyle Evans } 456*f0865ec9SKyle Evans if(ctx->dir == DES_ENCRYPTION){ 457*f0865ec9SKyle Evans if(des_core(&(ctx->des[0]), input, output)){ 458*f0865ec9SKyle Evans ret = -1; 459*f0865ec9SKyle Evans goto err; 460*f0865ec9SKyle Evans } 461*f0865ec9SKyle Evans if(des_core(&(ctx->des[1]), output, tmp)){ 462*f0865ec9SKyle Evans ret = -1; 463*f0865ec9SKyle Evans goto err; 464*f0865ec9SKyle Evans } 465*f0865ec9SKyle Evans if(des_core(&(ctx->des[2]), tmp, output)){ 466*f0865ec9SKyle Evans ret = -1; 467*f0865ec9SKyle Evans goto err; 468*f0865ec9SKyle Evans } 469*f0865ec9SKyle Evans } 470*f0865ec9SKyle Evans else if(ctx->dir == DES_DECRYPTION){ 471*f0865ec9SKyle Evans if(des_core(&(ctx->des[2]), input, output)){ 472*f0865ec9SKyle Evans ret = -1; 473*f0865ec9SKyle Evans goto err; 474*f0865ec9SKyle Evans } 475*f0865ec9SKyle Evans if(des_core(&(ctx->des[1]), output, tmp)){ 476*f0865ec9SKyle Evans ret = -1; 477*f0865ec9SKyle Evans goto err; 478*f0865ec9SKyle Evans } 479*f0865ec9SKyle Evans if(des_core(&(ctx->des[0]), tmp, output)){ 480*f0865ec9SKyle Evans ret = -1; 481*f0865ec9SKyle Evans goto err; 482*f0865ec9SKyle Evans } 483*f0865ec9SKyle Evans } 484*f0865ec9SKyle Evans else{ 485*f0865ec9SKyle Evans ret = -1; 486*f0865ec9SKyle Evans goto err; 487*f0865ec9SKyle Evans } 488*f0865ec9SKyle Evans 489*f0865ec9SKyle Evans ret = 0; 490*f0865ec9SKyle Evans err: 491*f0865ec9SKyle Evans return ret; 492*f0865ec9SKyle Evans } 493