1214501Srpaulo/* 2214501Srpaulo * DES and 3DES-EDE ciphers 3214501Srpaulo * 4214501Srpaulo * Modifications to LibTomCrypt implementation: 5214501Srpaulo * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi> 6214501Srpaulo * 7252726Srpaulo * This software may be distributed under the terms of the BSD license. 8252726Srpaulo * See README for more details. 9214501Srpaulo */ 10214501Srpaulo 11214501Srpaulo#include "includes.h" 12214501Srpaulo 13214501Srpaulo#include "common.h" 14214501Srpaulo#include "crypto.h" 15214501Srpaulo#include "des_i.h" 16214501Srpaulo 17214501Srpaulo/* 18214501Srpaulo * This implementation is based on a DES implementation included in 19214501Srpaulo * LibTomCrypt. The version here is modified to fit in wpa_supplicant/hostapd 20214501Srpaulo * coding style. 21214501Srpaulo */ 22214501Srpaulo 23214501Srpaulo/* LibTomCrypt, modular cryptographic library -- Tom St Denis 24214501Srpaulo * 25214501Srpaulo * LibTomCrypt is a library that provides various cryptographic 26214501Srpaulo * algorithms in a highly modular and flexible manner. 27214501Srpaulo * 28214501Srpaulo * The library is free for all purposes without any express 29214501Srpaulo * guarantee it works. 30214501Srpaulo * 31214501Srpaulo * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com 32214501Srpaulo */ 33214501Srpaulo 34214501Srpaulo/** 35214501Srpaulo DES code submitted by Dobes Vandermeer 36214501Srpaulo*/ 37214501Srpaulo 38214501Srpaulo#define ROLc(x, y) \ 39214501Srpaulo ((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \ 40214501Srpaulo (((unsigned long) (x) & 0xFFFFFFFFUL) >> \ 41214501Srpaulo (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) 42214501Srpaulo#define RORc(x, y) \ 43214501Srpaulo (((((unsigned long) (x) & 0xFFFFFFFFUL) >> \ 44214501Srpaulo (unsigned long) ((y) & 31)) | \ 45214501Srpaulo ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \ 46214501Srpaulo 0xFFFFFFFFUL) 47214501Srpaulo 48214501Srpaulo 49214501Srpaulostatic const u32 bytebit[8] = 50214501Srpaulo{ 51214501Srpaulo 0200, 0100, 040, 020, 010, 04, 02, 01 52214501Srpaulo}; 53214501Srpaulo 54214501Srpaulostatic const u32 bigbyte[24] = 55214501Srpaulo{ 56214501Srpaulo 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL, 57214501Srpaulo 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL, 58214501Srpaulo 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL, 59214501Srpaulo 0x800UL, 0x400UL, 0x200UL, 0x100UL, 60214501Srpaulo 0x80UL, 0x40UL, 0x20UL, 0x10UL, 61214501Srpaulo 0x8UL, 0x4UL, 0x2UL, 0x1L 62214501Srpaulo}; 63214501Srpaulo 64214501Srpaulo/* Use the key schedule specific in the standard (ANSI X3.92-1981) */ 65214501Srpaulo 66214501Srpaulostatic const u8 pc1[56] = { 67214501Srpaulo 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 68214501Srpaulo 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 69214501Srpaulo 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 70214501Srpaulo 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 71214501Srpaulo}; 72214501Srpaulo 73214501Srpaulostatic const u8 totrot[16] = { 74214501Srpaulo 1, 2, 4, 6, 75214501Srpaulo 8, 10, 12, 14, 76214501Srpaulo 15, 17, 19, 21, 77214501Srpaulo 23, 25, 27, 28 78214501Srpaulo}; 79214501Srpaulo 80214501Srpaulostatic const u8 pc2[48] = { 81214501Srpaulo 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 82214501Srpaulo 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 83214501Srpaulo 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 84214501Srpaulo 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 85214501Srpaulo}; 86214501Srpaulo 87214501Srpaulo 88214501Srpaulostatic const u32 SP1[64] = 89214501Srpaulo{ 90214501Srpaulo 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, 91214501Srpaulo 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL, 92214501Srpaulo 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, 93214501Srpaulo 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL, 94214501Srpaulo 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, 95214501Srpaulo 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL, 96214501Srpaulo 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, 97214501Srpaulo 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL, 98214501Srpaulo 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, 99214501Srpaulo 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL, 100214501Srpaulo 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, 101214501Srpaulo 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL, 102214501Srpaulo 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, 103214501Srpaulo 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL, 104214501Srpaulo 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, 105214501Srpaulo 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL 106214501Srpaulo}; 107214501Srpaulo 108214501Srpaulostatic const u32 SP2[64] = 109214501Srpaulo{ 110214501Srpaulo 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, 111214501Srpaulo 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL, 112214501Srpaulo 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, 113214501Srpaulo 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, 114214501Srpaulo 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, 115214501Srpaulo 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL, 116214501Srpaulo 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, 117214501Srpaulo 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL, 118214501Srpaulo 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, 119214501Srpaulo 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL, 120214501Srpaulo 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, 121214501Srpaulo 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL, 122214501Srpaulo 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, 123214501Srpaulo 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL, 124214501Srpaulo 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, 125214501Srpaulo 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL 126214501Srpaulo}; 127214501Srpaulo 128214501Srpaulostatic const u32 SP3[64] = 129214501Srpaulo{ 130214501Srpaulo 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, 131214501Srpaulo 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL, 132214501Srpaulo 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, 133214501Srpaulo 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL, 134214501Srpaulo 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, 135214501Srpaulo 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL, 136214501Srpaulo 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, 137214501Srpaulo 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL, 138214501Srpaulo 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, 139214501Srpaulo 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL, 140214501Srpaulo 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, 141214501Srpaulo 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL, 142214501Srpaulo 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, 143214501Srpaulo 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL, 144214501Srpaulo 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, 145214501Srpaulo 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL 146214501Srpaulo}; 147214501Srpaulo 148214501Srpaulostatic const u32 SP4[64] = 149214501Srpaulo{ 150214501Srpaulo 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, 151214501Srpaulo 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL, 152214501Srpaulo 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, 153214501Srpaulo 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL, 154214501Srpaulo 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, 155214501Srpaulo 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL, 156214501Srpaulo 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, 157214501Srpaulo 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL, 158214501Srpaulo 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, 159214501Srpaulo 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL, 160214501Srpaulo 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, 161214501Srpaulo 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, 162214501Srpaulo 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, 163214501Srpaulo 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL, 164214501Srpaulo 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, 165214501Srpaulo 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL 166214501Srpaulo}; 167214501Srpaulo 168214501Srpaulostatic const u32 SP5[64] = 169214501Srpaulo{ 170214501Srpaulo 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, 171214501Srpaulo 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL, 172214501Srpaulo 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, 173214501Srpaulo 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL, 174214501Srpaulo 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, 175214501Srpaulo 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL, 176214501Srpaulo 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, 177214501Srpaulo 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL, 178214501Srpaulo 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, 179214501Srpaulo 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL, 180214501Srpaulo 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, 181214501Srpaulo 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL, 182214501Srpaulo 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, 183214501Srpaulo 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL, 184214501Srpaulo 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, 185214501Srpaulo 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL 186214501Srpaulo}; 187214501Srpaulo 188214501Srpaulostatic const u32 SP6[64] = 189214501Srpaulo{ 190214501Srpaulo 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, 191214501Srpaulo 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL, 192214501Srpaulo 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, 193214501Srpaulo 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, 194214501Srpaulo 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, 195214501Srpaulo 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL, 196214501Srpaulo 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, 197214501Srpaulo 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL, 198214501Srpaulo 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, 199214501Srpaulo 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL, 200214501Srpaulo 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, 201214501Srpaulo 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL, 202214501Srpaulo 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, 203214501Srpaulo 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL, 204214501Srpaulo 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, 205214501Srpaulo 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL 206214501Srpaulo}; 207214501Srpaulo 208214501Srpaulostatic const u32 SP7[64] = 209214501Srpaulo{ 210214501Srpaulo 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, 211214501Srpaulo 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL, 212214501Srpaulo 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, 213214501Srpaulo 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL, 214214501Srpaulo 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, 215214501Srpaulo 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL, 216214501Srpaulo 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, 217214501Srpaulo 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL, 218214501Srpaulo 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, 219214501Srpaulo 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL, 220214501Srpaulo 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, 221214501Srpaulo 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL, 222214501Srpaulo 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, 223214501Srpaulo 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL, 224214501Srpaulo 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, 225214501Srpaulo 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL 226214501Srpaulo}; 227214501Srpaulo 228214501Srpaulostatic const u32 SP8[64] = 229214501Srpaulo{ 230214501Srpaulo 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, 231214501Srpaulo 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL, 232214501Srpaulo 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, 233214501Srpaulo 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL, 234214501Srpaulo 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, 235214501Srpaulo 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL, 236214501Srpaulo 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, 237214501Srpaulo 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL, 238214501Srpaulo 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, 239214501Srpaulo 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL, 240214501Srpaulo 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, 241214501Srpaulo 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL, 242214501Srpaulo 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, 243214501Srpaulo 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL, 244214501Srpaulo 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, 245214501Srpaulo 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL 246214501Srpaulo}; 247214501Srpaulo 248214501Srpaulo 249214501Srpaulostatic void cookey(const u32 *raw1, u32 *keyout) 250214501Srpaulo{ 251214501Srpaulo u32 *cook; 252214501Srpaulo const u32 *raw0; 253214501Srpaulo u32 dough[32]; 254214501Srpaulo int i; 255214501Srpaulo 256214501Srpaulo cook = dough; 257214501Srpaulo for (i = 0; i < 16; i++, raw1++) { 258214501Srpaulo raw0 = raw1++; 259214501Srpaulo *cook = (*raw0 & 0x00fc0000L) << 6; 260214501Srpaulo *cook |= (*raw0 & 0x00000fc0L) << 10; 261214501Srpaulo *cook |= (*raw1 & 0x00fc0000L) >> 10; 262214501Srpaulo *cook++ |= (*raw1 & 0x00000fc0L) >> 6; 263214501Srpaulo *cook = (*raw0 & 0x0003f000L) << 12; 264214501Srpaulo *cook |= (*raw0 & 0x0000003fL) << 16; 265214501Srpaulo *cook |= (*raw1 & 0x0003f000L) >> 4; 266214501Srpaulo *cook++ |= (*raw1 & 0x0000003fL); 267214501Srpaulo } 268214501Srpaulo 269214501Srpaulo os_memcpy(keyout, dough, sizeof(dough)); 270214501Srpaulo} 271214501Srpaulo 272214501Srpaulo 273214501Srpaulostatic void deskey(const u8 *key, int decrypt, u32 *keyout) 274214501Srpaulo{ 275214501Srpaulo u32 i, j, l, m, n, kn[32]; 276214501Srpaulo u8 pc1m[56], pcr[56]; 277214501Srpaulo 278214501Srpaulo for (j = 0; j < 56; j++) { 279214501Srpaulo l = (u32) pc1[j]; 280214501Srpaulo m = l & 7; 281214501Srpaulo pc1m[j] = (u8) 282214501Srpaulo ((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0); 283214501Srpaulo } 284214501Srpaulo 285214501Srpaulo for (i = 0; i < 16; i++) { 286214501Srpaulo if (decrypt) 287214501Srpaulo m = (15 - i) << 1; 288214501Srpaulo else 289214501Srpaulo m = i << 1; 290214501Srpaulo n = m + 1; 291214501Srpaulo kn[m] = kn[n] = 0L; 292214501Srpaulo for (j = 0; j < 28; j++) { 293214501Srpaulo l = j + (u32) totrot[i]; 294214501Srpaulo if (l < 28) 295214501Srpaulo pcr[j] = pc1m[l]; 296214501Srpaulo else 297214501Srpaulo pcr[j] = pc1m[l - 28]; 298214501Srpaulo } 299214501Srpaulo for (/* j = 28 */; j < 56; j++) { 300214501Srpaulo l = j + (u32) totrot[i]; 301214501Srpaulo if (l < 56) 302214501Srpaulo pcr[j] = pc1m[l]; 303214501Srpaulo else 304214501Srpaulo pcr[j] = pc1m[l - 28]; 305214501Srpaulo } 306214501Srpaulo for (j = 0; j < 24; j++) { 307214501Srpaulo if ((int) pcr[(int) pc2[j]] != 0) 308214501Srpaulo kn[m] |= bigbyte[j]; 309214501Srpaulo if ((int) pcr[(int) pc2[j + 24]] != 0) 310214501Srpaulo kn[n] |= bigbyte[j]; 311214501Srpaulo } 312214501Srpaulo } 313214501Srpaulo 314214501Srpaulo cookey(kn, keyout); 315214501Srpaulo} 316214501Srpaulo 317214501Srpaulo 318214501Srpaulostatic void desfunc(u32 *block, const u32 *keys) 319214501Srpaulo{ 320214501Srpaulo u32 work, right, leftt; 321214501Srpaulo int cur_round; 322214501Srpaulo 323214501Srpaulo leftt = block[0]; 324214501Srpaulo right = block[1]; 325214501Srpaulo 326214501Srpaulo work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; 327214501Srpaulo right ^= work; 328214501Srpaulo leftt ^= (work << 4); 329214501Srpaulo 330214501Srpaulo work = ((leftt >> 16) ^ right) & 0x0000ffffL; 331214501Srpaulo right ^= work; 332214501Srpaulo leftt ^= (work << 16); 333214501Srpaulo 334214501Srpaulo work = ((right >> 2) ^ leftt) & 0x33333333L; 335214501Srpaulo leftt ^= work; 336214501Srpaulo right ^= (work << 2); 337214501Srpaulo 338214501Srpaulo work = ((right >> 8) ^ leftt) & 0x00ff00ffL; 339214501Srpaulo leftt ^= work; 340214501Srpaulo right ^= (work << 8); 341214501Srpaulo 342214501Srpaulo right = ROLc(right, 1); 343214501Srpaulo work = (leftt ^ right) & 0xaaaaaaaaL; 344214501Srpaulo 345214501Srpaulo leftt ^= work; 346214501Srpaulo right ^= work; 347214501Srpaulo leftt = ROLc(leftt, 1); 348214501Srpaulo 349214501Srpaulo for (cur_round = 0; cur_round < 8; cur_round++) { 350214501Srpaulo work = RORc(right, 4) ^ *keys++; 351214501Srpaulo leftt ^= SP7[work & 0x3fL] 352214501Srpaulo ^ SP5[(work >> 8) & 0x3fL] 353214501Srpaulo ^ SP3[(work >> 16) & 0x3fL] 354214501Srpaulo ^ SP1[(work >> 24) & 0x3fL]; 355214501Srpaulo work = right ^ *keys++; 356214501Srpaulo leftt ^= SP8[ work & 0x3fL] 357214501Srpaulo ^ SP6[(work >> 8) & 0x3fL] 358214501Srpaulo ^ SP4[(work >> 16) & 0x3fL] 359214501Srpaulo ^ SP2[(work >> 24) & 0x3fL]; 360214501Srpaulo 361214501Srpaulo work = RORc(leftt, 4) ^ *keys++; 362214501Srpaulo right ^= SP7[ work & 0x3fL] 363214501Srpaulo ^ SP5[(work >> 8) & 0x3fL] 364214501Srpaulo ^ SP3[(work >> 16) & 0x3fL] 365214501Srpaulo ^ SP1[(work >> 24) & 0x3fL]; 366214501Srpaulo work = leftt ^ *keys++; 367214501Srpaulo right ^= SP8[ work & 0x3fL] 368214501Srpaulo ^ SP6[(work >> 8) & 0x3fL] 369214501Srpaulo ^ SP4[(work >> 16) & 0x3fL] 370214501Srpaulo ^ SP2[(work >> 24) & 0x3fL]; 371214501Srpaulo } 372214501Srpaulo 373214501Srpaulo right = RORc(right, 1); 374214501Srpaulo work = (leftt ^ right) & 0xaaaaaaaaL; 375214501Srpaulo leftt ^= work; 376214501Srpaulo right ^= work; 377214501Srpaulo leftt = RORc(leftt, 1); 378214501Srpaulo work = ((leftt >> 8) ^ right) & 0x00ff00ffL; 379214501Srpaulo right ^= work; 380214501Srpaulo leftt ^= (work << 8); 381214501Srpaulo /* -- */ 382214501Srpaulo work = ((leftt >> 2) ^ right) & 0x33333333L; 383214501Srpaulo right ^= work; 384214501Srpaulo leftt ^= (work << 2); 385214501Srpaulo work = ((right >> 16) ^ leftt) & 0x0000ffffL; 386214501Srpaulo leftt ^= work; 387214501Srpaulo right ^= (work << 16); 388214501Srpaulo work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; 389214501Srpaulo leftt ^= work; 390214501Srpaulo right ^= (work << 4); 391214501Srpaulo 392214501Srpaulo block[0] = right; 393214501Srpaulo block[1] = leftt; 394214501Srpaulo} 395214501Srpaulo 396214501Srpaulo 397214501Srpaulo/* wpa_supplicant/hostapd specific wrapper */ 398214501Srpaulo 399214501Srpaulovoid des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 400214501Srpaulo{ 401214501Srpaulo u8 pkey[8], next, tmp; 402214501Srpaulo int i; 403214501Srpaulo u32 ek[32], work[2]; 404214501Srpaulo 405214501Srpaulo /* Add parity bits to the key */ 406214501Srpaulo next = 0; 407214501Srpaulo for (i = 0; i < 7; i++) { 408214501Srpaulo tmp = key[i]; 409214501Srpaulo pkey[i] = (tmp >> i) | next | 1; 410214501Srpaulo next = tmp << (7 - i); 411214501Srpaulo } 412214501Srpaulo pkey[i] = next | 1; 413214501Srpaulo 414214501Srpaulo deskey(pkey, 0, ek); 415214501Srpaulo 416214501Srpaulo work[0] = WPA_GET_BE32(clear); 417214501Srpaulo work[1] = WPA_GET_BE32(clear + 4); 418214501Srpaulo desfunc(work, ek); 419214501Srpaulo WPA_PUT_BE32(cypher, work[0]); 420214501Srpaulo WPA_PUT_BE32(cypher + 4, work[1]); 421214501Srpaulo 422214501Srpaulo os_memset(pkey, 0, sizeof(pkey)); 423214501Srpaulo os_memset(ek, 0, sizeof(ek)); 424214501Srpaulo} 425214501Srpaulo 426214501Srpaulo 427214501Srpaulovoid des_key_setup(const u8 *key, u32 *ek, u32 *dk) 428214501Srpaulo{ 429214501Srpaulo deskey(key, 0, ek); 430214501Srpaulo deskey(key, 1, dk); 431214501Srpaulo} 432214501Srpaulo 433214501Srpaulo 434214501Srpaulovoid des_block_encrypt(const u8 *plain, const u32 *ek, u8 *crypt) 435214501Srpaulo{ 436214501Srpaulo u32 work[2]; 437214501Srpaulo work[0] = WPA_GET_BE32(plain); 438214501Srpaulo work[1] = WPA_GET_BE32(plain + 4); 439214501Srpaulo desfunc(work, ek); 440214501Srpaulo WPA_PUT_BE32(crypt, work[0]); 441214501Srpaulo WPA_PUT_BE32(crypt + 4, work[1]); 442214501Srpaulo} 443214501Srpaulo 444214501Srpaulo 445214501Srpaulovoid des_block_decrypt(const u8 *crypt, const u32 *dk, u8 *plain) 446214501Srpaulo{ 447214501Srpaulo u32 work[2]; 448214501Srpaulo work[0] = WPA_GET_BE32(crypt); 449214501Srpaulo work[1] = WPA_GET_BE32(crypt + 4); 450214501Srpaulo desfunc(work, dk); 451214501Srpaulo WPA_PUT_BE32(plain, work[0]); 452214501Srpaulo WPA_PUT_BE32(plain + 4, work[1]); 453214501Srpaulo} 454214501Srpaulo 455214501Srpaulo 456214501Srpaulovoid des3_key_setup(const u8 *key, struct des3_key_s *dkey) 457214501Srpaulo{ 458214501Srpaulo deskey(key, 0, dkey->ek[0]); 459214501Srpaulo deskey(key + 8, 1, dkey->ek[1]); 460214501Srpaulo deskey(key + 16, 0, dkey->ek[2]); 461214501Srpaulo 462214501Srpaulo deskey(key, 1, dkey->dk[2]); 463214501Srpaulo deskey(key + 8, 0, dkey->dk[1]); 464214501Srpaulo deskey(key + 16, 1, dkey->dk[0]); 465214501Srpaulo} 466214501Srpaulo 467214501Srpaulo 468214501Srpaulovoid des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt) 469214501Srpaulo{ 470214501Srpaulo u32 work[2]; 471214501Srpaulo 472214501Srpaulo work[0] = WPA_GET_BE32(plain); 473214501Srpaulo work[1] = WPA_GET_BE32(plain + 4); 474214501Srpaulo desfunc(work, key->ek[0]); 475214501Srpaulo desfunc(work, key->ek[1]); 476214501Srpaulo desfunc(work, key->ek[2]); 477214501Srpaulo WPA_PUT_BE32(crypt, work[0]); 478214501Srpaulo WPA_PUT_BE32(crypt + 4, work[1]); 479214501Srpaulo} 480214501Srpaulo 481214501Srpaulo 482214501Srpaulovoid des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain) 483214501Srpaulo{ 484214501Srpaulo u32 work[2]; 485214501Srpaulo 486214501Srpaulo work[0] = WPA_GET_BE32(crypt); 487214501Srpaulo work[1] = WPA_GET_BE32(crypt + 4); 488214501Srpaulo desfunc(work, key->dk[0]); 489214501Srpaulo desfunc(work, key->dk[1]); 490214501Srpaulo desfunc(work, key->dk[2]); 491214501Srpaulo WPA_PUT_BE32(plain, work[0]); 492214501Srpaulo WPA_PUT_BE32(plain + 4, work[1]); 493214501Srpaulo} 494