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