1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * DES and 3DES-EDE ciphers 3e5b75505Sopenharmony_ci * 4e5b75505Sopenharmony_ci * Modifications to LibTomCrypt implementation: 5e5b75505Sopenharmony_ci * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi> 6e5b75505Sopenharmony_ci * 7e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 8e5b75505Sopenharmony_ci * See README for more details. 9e5b75505Sopenharmony_ci */ 10e5b75505Sopenharmony_ci 11e5b75505Sopenharmony_ci#include "includes.h" 12e5b75505Sopenharmony_ci 13e5b75505Sopenharmony_ci#include "common.h" 14e5b75505Sopenharmony_ci#include "crypto.h" 15e5b75505Sopenharmony_ci#include "des_i.h" 16e5b75505Sopenharmony_ci 17e5b75505Sopenharmony_ci/* 18e5b75505Sopenharmony_ci * This implementation is based on a DES implementation included in 19e5b75505Sopenharmony_ci * LibTomCrypt. The version here is modified to fit in wpa_supplicant/hostapd 20e5b75505Sopenharmony_ci * coding style. 21e5b75505Sopenharmony_ci */ 22e5b75505Sopenharmony_ci 23e5b75505Sopenharmony_ci/* LibTomCrypt, modular cryptographic library -- Tom St Denis 24e5b75505Sopenharmony_ci * 25e5b75505Sopenharmony_ci * LibTomCrypt is a library that provides various cryptographic 26e5b75505Sopenharmony_ci * algorithms in a highly modular and flexible manner. 27e5b75505Sopenharmony_ci * 28e5b75505Sopenharmony_ci * The library is free for all purposes without any express 29e5b75505Sopenharmony_ci * guarantee it works. 30e5b75505Sopenharmony_ci * 31e5b75505Sopenharmony_ci * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com 32e5b75505Sopenharmony_ci */ 33e5b75505Sopenharmony_ci 34e5b75505Sopenharmony_ci/** 35e5b75505Sopenharmony_ci DES code submitted by Dobes Vandermeer 36e5b75505Sopenharmony_ci*/ 37e5b75505Sopenharmony_ci 38e5b75505Sopenharmony_ci#define ROLc(x, y) \ 39e5b75505Sopenharmony_ci ((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \ 40e5b75505Sopenharmony_ci (((unsigned long) (x) & 0xFFFFFFFFUL) >> \ 41e5b75505Sopenharmony_ci (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) 42e5b75505Sopenharmony_ci#define RORc(x, y) \ 43e5b75505Sopenharmony_ci (((((unsigned long) (x) & 0xFFFFFFFFUL) >> \ 44e5b75505Sopenharmony_ci (unsigned long) ((y) & 31)) | \ 45e5b75505Sopenharmony_ci ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \ 46e5b75505Sopenharmony_ci 0xFFFFFFFFUL) 47e5b75505Sopenharmony_ci 48e5b75505Sopenharmony_ci 49e5b75505Sopenharmony_cistatic const u32 bytebit[8] = 50e5b75505Sopenharmony_ci{ 51e5b75505Sopenharmony_ci 0200, 0100, 040, 020, 010, 04, 02, 01 52e5b75505Sopenharmony_ci}; 53e5b75505Sopenharmony_ci 54e5b75505Sopenharmony_cistatic const u32 bigbyte[24] = 55e5b75505Sopenharmony_ci{ 56e5b75505Sopenharmony_ci 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL, 57e5b75505Sopenharmony_ci 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL, 58e5b75505Sopenharmony_ci 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL, 59e5b75505Sopenharmony_ci 0x800UL, 0x400UL, 0x200UL, 0x100UL, 60e5b75505Sopenharmony_ci 0x80UL, 0x40UL, 0x20UL, 0x10UL, 61e5b75505Sopenharmony_ci 0x8UL, 0x4UL, 0x2UL, 0x1L 62e5b75505Sopenharmony_ci}; 63e5b75505Sopenharmony_ci 64e5b75505Sopenharmony_ci/* Use the key schedule specific in the standard (ANSI X3.92-1981) */ 65e5b75505Sopenharmony_ci 66e5b75505Sopenharmony_cistatic const u8 pc1[56] = { 67e5b75505Sopenharmony_ci 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 68e5b75505Sopenharmony_ci 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 69e5b75505Sopenharmony_ci 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 70e5b75505Sopenharmony_ci 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 71e5b75505Sopenharmony_ci}; 72e5b75505Sopenharmony_ci 73e5b75505Sopenharmony_cistatic const u8 totrot[16] = { 74e5b75505Sopenharmony_ci 1, 2, 4, 6, 75e5b75505Sopenharmony_ci 8, 10, 12, 14, 76e5b75505Sopenharmony_ci 15, 17, 19, 21, 77e5b75505Sopenharmony_ci 23, 25, 27, 28 78e5b75505Sopenharmony_ci}; 79e5b75505Sopenharmony_ci 80e5b75505Sopenharmony_cistatic const u8 pc2[48] = { 81e5b75505Sopenharmony_ci 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 82e5b75505Sopenharmony_ci 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 83e5b75505Sopenharmony_ci 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 84e5b75505Sopenharmony_ci 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 85e5b75505Sopenharmony_ci}; 86e5b75505Sopenharmony_ci 87e5b75505Sopenharmony_ci 88e5b75505Sopenharmony_cistatic const u32 SP1[64] = 89e5b75505Sopenharmony_ci{ 90e5b75505Sopenharmony_ci 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, 91e5b75505Sopenharmony_ci 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL, 92e5b75505Sopenharmony_ci 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, 93e5b75505Sopenharmony_ci 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL, 94e5b75505Sopenharmony_ci 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, 95e5b75505Sopenharmony_ci 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL, 96e5b75505Sopenharmony_ci 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, 97e5b75505Sopenharmony_ci 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL, 98e5b75505Sopenharmony_ci 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, 99e5b75505Sopenharmony_ci 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL, 100e5b75505Sopenharmony_ci 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, 101e5b75505Sopenharmony_ci 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL, 102e5b75505Sopenharmony_ci 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, 103e5b75505Sopenharmony_ci 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL, 104e5b75505Sopenharmony_ci 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, 105e5b75505Sopenharmony_ci 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL 106e5b75505Sopenharmony_ci}; 107e5b75505Sopenharmony_ci 108e5b75505Sopenharmony_cistatic const u32 SP2[64] = 109e5b75505Sopenharmony_ci{ 110e5b75505Sopenharmony_ci 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, 111e5b75505Sopenharmony_ci 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL, 112e5b75505Sopenharmony_ci 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, 113e5b75505Sopenharmony_ci 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, 114e5b75505Sopenharmony_ci 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, 115e5b75505Sopenharmony_ci 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL, 116e5b75505Sopenharmony_ci 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, 117e5b75505Sopenharmony_ci 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL, 118e5b75505Sopenharmony_ci 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, 119e5b75505Sopenharmony_ci 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL, 120e5b75505Sopenharmony_ci 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, 121e5b75505Sopenharmony_ci 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL, 122e5b75505Sopenharmony_ci 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, 123e5b75505Sopenharmony_ci 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL, 124e5b75505Sopenharmony_ci 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, 125e5b75505Sopenharmony_ci 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL 126e5b75505Sopenharmony_ci}; 127e5b75505Sopenharmony_ci 128e5b75505Sopenharmony_cistatic const u32 SP3[64] = 129e5b75505Sopenharmony_ci{ 130e5b75505Sopenharmony_ci 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, 131e5b75505Sopenharmony_ci 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL, 132e5b75505Sopenharmony_ci 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, 133e5b75505Sopenharmony_ci 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL, 134e5b75505Sopenharmony_ci 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, 135e5b75505Sopenharmony_ci 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL, 136e5b75505Sopenharmony_ci 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, 137e5b75505Sopenharmony_ci 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL, 138e5b75505Sopenharmony_ci 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, 139e5b75505Sopenharmony_ci 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL, 140e5b75505Sopenharmony_ci 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, 141e5b75505Sopenharmony_ci 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL, 142e5b75505Sopenharmony_ci 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, 143e5b75505Sopenharmony_ci 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL, 144e5b75505Sopenharmony_ci 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, 145e5b75505Sopenharmony_ci 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL 146e5b75505Sopenharmony_ci}; 147e5b75505Sopenharmony_ci 148e5b75505Sopenharmony_cistatic const u32 SP4[64] = 149e5b75505Sopenharmony_ci{ 150e5b75505Sopenharmony_ci 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, 151e5b75505Sopenharmony_ci 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL, 152e5b75505Sopenharmony_ci 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, 153e5b75505Sopenharmony_ci 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL, 154e5b75505Sopenharmony_ci 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, 155e5b75505Sopenharmony_ci 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL, 156e5b75505Sopenharmony_ci 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, 157e5b75505Sopenharmony_ci 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL, 158e5b75505Sopenharmony_ci 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, 159e5b75505Sopenharmony_ci 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL, 160e5b75505Sopenharmony_ci 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, 161e5b75505Sopenharmony_ci 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, 162e5b75505Sopenharmony_ci 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, 163e5b75505Sopenharmony_ci 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL, 164e5b75505Sopenharmony_ci 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, 165e5b75505Sopenharmony_ci 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL 166e5b75505Sopenharmony_ci}; 167e5b75505Sopenharmony_ci 168e5b75505Sopenharmony_cistatic const u32 SP5[64] = 169e5b75505Sopenharmony_ci{ 170e5b75505Sopenharmony_ci 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, 171e5b75505Sopenharmony_ci 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL, 172e5b75505Sopenharmony_ci 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, 173e5b75505Sopenharmony_ci 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL, 174e5b75505Sopenharmony_ci 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, 175e5b75505Sopenharmony_ci 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL, 176e5b75505Sopenharmony_ci 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, 177e5b75505Sopenharmony_ci 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL, 178e5b75505Sopenharmony_ci 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, 179e5b75505Sopenharmony_ci 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL, 180e5b75505Sopenharmony_ci 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, 181e5b75505Sopenharmony_ci 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL, 182e5b75505Sopenharmony_ci 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, 183e5b75505Sopenharmony_ci 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL, 184e5b75505Sopenharmony_ci 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, 185e5b75505Sopenharmony_ci 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL 186e5b75505Sopenharmony_ci}; 187e5b75505Sopenharmony_ci 188e5b75505Sopenharmony_cistatic const u32 SP6[64] = 189e5b75505Sopenharmony_ci{ 190e5b75505Sopenharmony_ci 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, 191e5b75505Sopenharmony_ci 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL, 192e5b75505Sopenharmony_ci 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, 193e5b75505Sopenharmony_ci 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, 194e5b75505Sopenharmony_ci 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, 195e5b75505Sopenharmony_ci 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL, 196e5b75505Sopenharmony_ci 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, 197e5b75505Sopenharmony_ci 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL, 198e5b75505Sopenharmony_ci 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, 199e5b75505Sopenharmony_ci 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL, 200e5b75505Sopenharmony_ci 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, 201e5b75505Sopenharmony_ci 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL, 202e5b75505Sopenharmony_ci 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, 203e5b75505Sopenharmony_ci 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL, 204e5b75505Sopenharmony_ci 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, 205e5b75505Sopenharmony_ci 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL 206e5b75505Sopenharmony_ci}; 207e5b75505Sopenharmony_ci 208e5b75505Sopenharmony_cistatic const u32 SP7[64] = 209e5b75505Sopenharmony_ci{ 210e5b75505Sopenharmony_ci 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, 211e5b75505Sopenharmony_ci 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL, 212e5b75505Sopenharmony_ci 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, 213e5b75505Sopenharmony_ci 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL, 214e5b75505Sopenharmony_ci 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, 215e5b75505Sopenharmony_ci 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL, 216e5b75505Sopenharmony_ci 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, 217e5b75505Sopenharmony_ci 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL, 218e5b75505Sopenharmony_ci 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, 219e5b75505Sopenharmony_ci 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL, 220e5b75505Sopenharmony_ci 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, 221e5b75505Sopenharmony_ci 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL, 222e5b75505Sopenharmony_ci 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, 223e5b75505Sopenharmony_ci 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL, 224e5b75505Sopenharmony_ci 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, 225e5b75505Sopenharmony_ci 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL 226e5b75505Sopenharmony_ci}; 227e5b75505Sopenharmony_ci 228e5b75505Sopenharmony_cistatic const u32 SP8[64] = 229e5b75505Sopenharmony_ci{ 230e5b75505Sopenharmony_ci 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, 231e5b75505Sopenharmony_ci 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL, 232e5b75505Sopenharmony_ci 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, 233e5b75505Sopenharmony_ci 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL, 234e5b75505Sopenharmony_ci 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, 235e5b75505Sopenharmony_ci 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL, 236e5b75505Sopenharmony_ci 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, 237e5b75505Sopenharmony_ci 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL, 238e5b75505Sopenharmony_ci 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, 239e5b75505Sopenharmony_ci 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL, 240e5b75505Sopenharmony_ci 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, 241e5b75505Sopenharmony_ci 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL, 242e5b75505Sopenharmony_ci 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, 243e5b75505Sopenharmony_ci 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL, 244e5b75505Sopenharmony_ci 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, 245e5b75505Sopenharmony_ci 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL 246e5b75505Sopenharmony_ci}; 247e5b75505Sopenharmony_ci 248e5b75505Sopenharmony_ci 249e5b75505Sopenharmony_cistatic void cookey(const u32 *raw1, u32 *keyout) 250e5b75505Sopenharmony_ci{ 251e5b75505Sopenharmony_ci u32 *cook; 252e5b75505Sopenharmony_ci const u32 *raw0; 253e5b75505Sopenharmony_ci u32 dough[32]; 254e5b75505Sopenharmony_ci int i; 255e5b75505Sopenharmony_ci 256e5b75505Sopenharmony_ci cook = dough; 257e5b75505Sopenharmony_ci for (i = 0; i < 16; i++, raw1++) { 258e5b75505Sopenharmony_ci raw0 = raw1++; 259e5b75505Sopenharmony_ci *cook = (*raw0 & 0x00fc0000L) << 6; 260e5b75505Sopenharmony_ci *cook |= (*raw0 & 0x00000fc0L) << 10; 261e5b75505Sopenharmony_ci *cook |= (*raw1 & 0x00fc0000L) >> 10; 262e5b75505Sopenharmony_ci *cook++ |= (*raw1 & 0x00000fc0L) >> 6; 263e5b75505Sopenharmony_ci *cook = (*raw0 & 0x0003f000L) << 12; 264e5b75505Sopenharmony_ci *cook |= (*raw0 & 0x0000003fL) << 16; 265e5b75505Sopenharmony_ci *cook |= (*raw1 & 0x0003f000L) >> 4; 266e5b75505Sopenharmony_ci *cook++ |= (*raw1 & 0x0000003fL); 267e5b75505Sopenharmony_ci } 268e5b75505Sopenharmony_ci 269e5b75505Sopenharmony_ci os_memcpy(keyout, dough, sizeof(dough)); 270e5b75505Sopenharmony_ci} 271e5b75505Sopenharmony_ci 272e5b75505Sopenharmony_ci 273e5b75505Sopenharmony_cistatic void deskey(const u8 *key, int decrypt, u32 *keyout) 274e5b75505Sopenharmony_ci{ 275e5b75505Sopenharmony_ci u32 i, j, l, m, n, kn[32]; 276e5b75505Sopenharmony_ci u8 pc1m[56], pcr[56]; 277e5b75505Sopenharmony_ci 278e5b75505Sopenharmony_ci for (j = 0; j < 56; j++) { 279e5b75505Sopenharmony_ci l = (u32) pc1[j]; 280e5b75505Sopenharmony_ci m = l & 7; 281e5b75505Sopenharmony_ci pc1m[j] = (u8) 282e5b75505Sopenharmony_ci ((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0); 283e5b75505Sopenharmony_ci } 284e5b75505Sopenharmony_ci 285e5b75505Sopenharmony_ci for (i = 0; i < 16; i++) { 286e5b75505Sopenharmony_ci if (decrypt) 287e5b75505Sopenharmony_ci m = (15 - i) << 1; 288e5b75505Sopenharmony_ci else 289e5b75505Sopenharmony_ci m = i << 1; 290e5b75505Sopenharmony_ci n = m + 1; 291e5b75505Sopenharmony_ci kn[m] = kn[n] = 0L; 292e5b75505Sopenharmony_ci for (j = 0; j < 28; j++) { 293e5b75505Sopenharmony_ci l = j + (u32) totrot[i]; 294e5b75505Sopenharmony_ci if (l < 28) 295e5b75505Sopenharmony_ci pcr[j] = pc1m[l]; 296e5b75505Sopenharmony_ci else 297e5b75505Sopenharmony_ci pcr[j] = pc1m[l - 28]; 298e5b75505Sopenharmony_ci } 299e5b75505Sopenharmony_ci for (/* j = 28 */; j < 56; j++) { 300e5b75505Sopenharmony_ci l = j + (u32) totrot[i]; 301e5b75505Sopenharmony_ci if (l < 56) 302e5b75505Sopenharmony_ci pcr[j] = pc1m[l]; 303e5b75505Sopenharmony_ci else 304e5b75505Sopenharmony_ci pcr[j] = pc1m[l - 28]; 305e5b75505Sopenharmony_ci } 306e5b75505Sopenharmony_ci for (j = 0; j < 24; j++) { 307e5b75505Sopenharmony_ci if ((int) pcr[(int) pc2[j]] != 0) 308e5b75505Sopenharmony_ci kn[m] |= bigbyte[j]; 309e5b75505Sopenharmony_ci if ((int) pcr[(int) pc2[j + 24]] != 0) 310e5b75505Sopenharmony_ci kn[n] |= bigbyte[j]; 311e5b75505Sopenharmony_ci } 312e5b75505Sopenharmony_ci } 313e5b75505Sopenharmony_ci 314e5b75505Sopenharmony_ci cookey(kn, keyout); 315e5b75505Sopenharmony_ci} 316e5b75505Sopenharmony_ci 317e5b75505Sopenharmony_ci 318e5b75505Sopenharmony_cistatic void desfunc(u32 *block, const u32 *keys) 319e5b75505Sopenharmony_ci{ 320e5b75505Sopenharmony_ci u32 work, right, leftt; 321e5b75505Sopenharmony_ci int cur_round; 322e5b75505Sopenharmony_ci 323e5b75505Sopenharmony_ci leftt = block[0]; 324e5b75505Sopenharmony_ci right = block[1]; 325e5b75505Sopenharmony_ci 326e5b75505Sopenharmony_ci work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; 327e5b75505Sopenharmony_ci right ^= work; 328e5b75505Sopenharmony_ci leftt ^= (work << 4); 329e5b75505Sopenharmony_ci 330e5b75505Sopenharmony_ci work = ((leftt >> 16) ^ right) & 0x0000ffffL; 331e5b75505Sopenharmony_ci right ^= work; 332e5b75505Sopenharmony_ci leftt ^= (work << 16); 333e5b75505Sopenharmony_ci 334e5b75505Sopenharmony_ci work = ((right >> 2) ^ leftt) & 0x33333333L; 335e5b75505Sopenharmony_ci leftt ^= work; 336e5b75505Sopenharmony_ci right ^= (work << 2); 337e5b75505Sopenharmony_ci 338e5b75505Sopenharmony_ci work = ((right >> 8) ^ leftt) & 0x00ff00ffL; 339e5b75505Sopenharmony_ci leftt ^= work; 340e5b75505Sopenharmony_ci right ^= (work << 8); 341e5b75505Sopenharmony_ci 342e5b75505Sopenharmony_ci right = ROLc(right, 1); 343e5b75505Sopenharmony_ci work = (leftt ^ right) & 0xaaaaaaaaL; 344e5b75505Sopenharmony_ci 345e5b75505Sopenharmony_ci leftt ^= work; 346e5b75505Sopenharmony_ci right ^= work; 347e5b75505Sopenharmony_ci leftt = ROLc(leftt, 1); 348e5b75505Sopenharmony_ci 349e5b75505Sopenharmony_ci for (cur_round = 0; cur_round < 8; cur_round++) { 350e5b75505Sopenharmony_ci work = RORc(right, 4) ^ *keys++; 351e5b75505Sopenharmony_ci leftt ^= SP7[work & 0x3fL] 352e5b75505Sopenharmony_ci ^ SP5[(work >> 8) & 0x3fL] 353e5b75505Sopenharmony_ci ^ SP3[(work >> 16) & 0x3fL] 354e5b75505Sopenharmony_ci ^ SP1[(work >> 24) & 0x3fL]; 355e5b75505Sopenharmony_ci work = right ^ *keys++; 356e5b75505Sopenharmony_ci leftt ^= SP8[ work & 0x3fL] 357e5b75505Sopenharmony_ci ^ SP6[(work >> 8) & 0x3fL] 358e5b75505Sopenharmony_ci ^ SP4[(work >> 16) & 0x3fL] 359e5b75505Sopenharmony_ci ^ SP2[(work >> 24) & 0x3fL]; 360e5b75505Sopenharmony_ci 361e5b75505Sopenharmony_ci work = RORc(leftt, 4) ^ *keys++; 362e5b75505Sopenharmony_ci right ^= SP7[ work & 0x3fL] 363e5b75505Sopenharmony_ci ^ SP5[(work >> 8) & 0x3fL] 364e5b75505Sopenharmony_ci ^ SP3[(work >> 16) & 0x3fL] 365e5b75505Sopenharmony_ci ^ SP1[(work >> 24) & 0x3fL]; 366e5b75505Sopenharmony_ci work = leftt ^ *keys++; 367e5b75505Sopenharmony_ci right ^= SP8[ work & 0x3fL] 368e5b75505Sopenharmony_ci ^ SP6[(work >> 8) & 0x3fL] 369e5b75505Sopenharmony_ci ^ SP4[(work >> 16) & 0x3fL] 370e5b75505Sopenharmony_ci ^ SP2[(work >> 24) & 0x3fL]; 371e5b75505Sopenharmony_ci } 372e5b75505Sopenharmony_ci 373e5b75505Sopenharmony_ci right = RORc(right, 1); 374e5b75505Sopenharmony_ci work = (leftt ^ right) & 0xaaaaaaaaL; 375e5b75505Sopenharmony_ci leftt ^= work; 376e5b75505Sopenharmony_ci right ^= work; 377e5b75505Sopenharmony_ci leftt = RORc(leftt, 1); 378e5b75505Sopenharmony_ci work = ((leftt >> 8) ^ right) & 0x00ff00ffL; 379e5b75505Sopenharmony_ci right ^= work; 380e5b75505Sopenharmony_ci leftt ^= (work << 8); 381e5b75505Sopenharmony_ci /* -- */ 382e5b75505Sopenharmony_ci work = ((leftt >> 2) ^ right) & 0x33333333L; 383e5b75505Sopenharmony_ci right ^= work; 384e5b75505Sopenharmony_ci leftt ^= (work << 2); 385e5b75505Sopenharmony_ci work = ((right >> 16) ^ leftt) & 0x0000ffffL; 386e5b75505Sopenharmony_ci leftt ^= work; 387e5b75505Sopenharmony_ci right ^= (work << 16); 388e5b75505Sopenharmony_ci work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; 389e5b75505Sopenharmony_ci leftt ^= work; 390e5b75505Sopenharmony_ci right ^= (work << 4); 391e5b75505Sopenharmony_ci 392e5b75505Sopenharmony_ci block[0] = right; 393e5b75505Sopenharmony_ci block[1] = leftt; 394e5b75505Sopenharmony_ci} 395e5b75505Sopenharmony_ci 396e5b75505Sopenharmony_ci 397e5b75505Sopenharmony_ci/* wpa_supplicant/hostapd specific wrapper */ 398e5b75505Sopenharmony_ci 399e5b75505Sopenharmony_ciint des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 400e5b75505Sopenharmony_ci{ 401e5b75505Sopenharmony_ci u8 pkey[8], next, tmp; 402e5b75505Sopenharmony_ci int i; 403e5b75505Sopenharmony_ci u32 ek[32], work[2]; 404e5b75505Sopenharmony_ci 405e5b75505Sopenharmony_ci /* Add parity bits to the key */ 406e5b75505Sopenharmony_ci next = 0; 407e5b75505Sopenharmony_ci for (i = 0; i < 7; i++) { 408e5b75505Sopenharmony_ci tmp = key[i]; 409e5b75505Sopenharmony_ci pkey[i] = (tmp >> i) | next | 1; 410e5b75505Sopenharmony_ci next = tmp << (7 - i); 411e5b75505Sopenharmony_ci } 412e5b75505Sopenharmony_ci pkey[i] = next | 1; 413e5b75505Sopenharmony_ci 414e5b75505Sopenharmony_ci deskey(pkey, 0, ek); 415e5b75505Sopenharmony_ci 416e5b75505Sopenharmony_ci work[0] = WPA_GET_BE32(clear); 417e5b75505Sopenharmony_ci work[1] = WPA_GET_BE32(clear + 4); 418e5b75505Sopenharmony_ci desfunc(work, ek); 419e5b75505Sopenharmony_ci WPA_PUT_BE32(cypher, work[0]); 420e5b75505Sopenharmony_ci WPA_PUT_BE32(cypher + 4, work[1]); 421e5b75505Sopenharmony_ci 422e5b75505Sopenharmony_ci os_memset(pkey, 0, sizeof(pkey)); 423e5b75505Sopenharmony_ci os_memset(ek, 0, sizeof(ek)); 424e5b75505Sopenharmony_ci return 0; 425e5b75505Sopenharmony_ci} 426e5b75505Sopenharmony_ci 427e5b75505Sopenharmony_ci 428e5b75505Sopenharmony_civoid des_key_setup(const u8 *key, u32 *ek, u32 *dk) 429e5b75505Sopenharmony_ci{ 430e5b75505Sopenharmony_ci deskey(key, 0, ek); 431e5b75505Sopenharmony_ci deskey(key, 1, dk); 432e5b75505Sopenharmony_ci} 433e5b75505Sopenharmony_ci 434e5b75505Sopenharmony_ci 435e5b75505Sopenharmony_civoid des_block_encrypt(const u8 *plain, const u32 *ek, u8 *crypt) 436e5b75505Sopenharmony_ci{ 437e5b75505Sopenharmony_ci u32 work[2]; 438e5b75505Sopenharmony_ci work[0] = WPA_GET_BE32(plain); 439e5b75505Sopenharmony_ci work[1] = WPA_GET_BE32(plain + 4); 440e5b75505Sopenharmony_ci desfunc(work, ek); 441e5b75505Sopenharmony_ci WPA_PUT_BE32(crypt, work[0]); 442e5b75505Sopenharmony_ci WPA_PUT_BE32(crypt + 4, work[1]); 443e5b75505Sopenharmony_ci} 444e5b75505Sopenharmony_ci 445e5b75505Sopenharmony_ci 446e5b75505Sopenharmony_civoid des_block_decrypt(const u8 *crypt, const u32 *dk, u8 *plain) 447e5b75505Sopenharmony_ci{ 448e5b75505Sopenharmony_ci u32 work[2]; 449e5b75505Sopenharmony_ci work[0] = WPA_GET_BE32(crypt); 450e5b75505Sopenharmony_ci work[1] = WPA_GET_BE32(crypt + 4); 451e5b75505Sopenharmony_ci desfunc(work, dk); 452e5b75505Sopenharmony_ci WPA_PUT_BE32(plain, work[0]); 453e5b75505Sopenharmony_ci WPA_PUT_BE32(plain + 4, work[1]); 454e5b75505Sopenharmony_ci} 455e5b75505Sopenharmony_ci 456e5b75505Sopenharmony_ci 457e5b75505Sopenharmony_civoid des3_key_setup(const u8 *key, struct des3_key_s *dkey) 458e5b75505Sopenharmony_ci{ 459e5b75505Sopenharmony_ci deskey(key, 0, dkey->ek[0]); 460e5b75505Sopenharmony_ci deskey(key + 8, 1, dkey->ek[1]); 461e5b75505Sopenharmony_ci deskey(key + 16, 0, dkey->ek[2]); 462e5b75505Sopenharmony_ci 463e5b75505Sopenharmony_ci deskey(key, 1, dkey->dk[2]); 464e5b75505Sopenharmony_ci deskey(key + 8, 0, dkey->dk[1]); 465e5b75505Sopenharmony_ci deskey(key + 16, 1, dkey->dk[0]); 466e5b75505Sopenharmony_ci} 467e5b75505Sopenharmony_ci 468e5b75505Sopenharmony_ci 469e5b75505Sopenharmony_civoid des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt) 470e5b75505Sopenharmony_ci{ 471e5b75505Sopenharmony_ci u32 work[2]; 472e5b75505Sopenharmony_ci 473e5b75505Sopenharmony_ci work[0] = WPA_GET_BE32(plain); 474e5b75505Sopenharmony_ci work[1] = WPA_GET_BE32(plain + 4); 475e5b75505Sopenharmony_ci desfunc(work, key->ek[0]); 476e5b75505Sopenharmony_ci desfunc(work, key->ek[1]); 477e5b75505Sopenharmony_ci desfunc(work, key->ek[2]); 478e5b75505Sopenharmony_ci WPA_PUT_BE32(crypt, work[0]); 479e5b75505Sopenharmony_ci WPA_PUT_BE32(crypt + 4, work[1]); 480e5b75505Sopenharmony_ci} 481e5b75505Sopenharmony_ci 482e5b75505Sopenharmony_ci 483e5b75505Sopenharmony_civoid des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain) 484e5b75505Sopenharmony_ci{ 485e5b75505Sopenharmony_ci u32 work[2]; 486e5b75505Sopenharmony_ci 487e5b75505Sopenharmony_ci work[0] = WPA_GET_BE32(crypt); 488e5b75505Sopenharmony_ci work[1] = WPA_GET_BE32(crypt + 4); 489e5b75505Sopenharmony_ci desfunc(work, key->dk[0]); 490e5b75505Sopenharmony_ci desfunc(work, key->dk[1]); 491e5b75505Sopenharmony_ci desfunc(work, key->dk[2]); 492e5b75505Sopenharmony_ci WPA_PUT_BE32(plain, work[0]); 493e5b75505Sopenharmony_ci WPA_PUT_BE32(plain + 4, work[1]); 494e5b75505Sopenharmony_ci} 495