/* Validation sets: * * Single-length key, single-length plaintext - * Key : 0123 4567 89ab cdef * Plain : 0123 4567 89ab cde7 * Cipher : c957 4425 6a5e d31d * * Double-length key, single-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 * Plain : 0123 4567 89ab cde7 * Cipher : 7f1d 0a77 826b 8aff * * Double-length key, double-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 * * Triple-length key, single-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 * Plain : 0123 4567 89ab cde7 * Cipher : de0b 7c06 ae5e 0ed5 * * Triple-length key, double-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 * * d3des V5.0a rwo 9208.07 18:44 Graven Imagery **********************************************************************/
/* ========================================================================== ** * * DES.c * * Copyright: * Copyright (C) 2003, 2004 by Christopher R. Hertel * * Email: crh@ubiqx.mn.org * * $Id: DES.c,v 0.7 2009/04/08 06:47:39 crh Exp $ * * -------------------------------------------------------------------------- ** * * Description: * * Implements DES encryption, but not decryption. * DES is used to create LM password hashes and both LM and NTLM Responses. * * -------------------------------------------------------------------------- ** * * License: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * -------------------------------------------------------------------------- ** * * Notes: * * This implementation was created by studying many existing examples * found in Open Source, in the public domain, and in various documentation. * The SMB protocol makes minimal use of the DES function, so this is a * minimal implementation. That which is not required has been removed. * * The SMB protocol uses the DES algorithm as a hash function, not an * encryption function. The auth_DEShash() implemented here is a one-way * function. The reverse is not implemented in this module. Also, there * is no attempt at making this either fast or efficient. There is no * need, as the auth_DEShash() function is used for generating the LM * Response from a 7-byte key and an 8-byte challenge. It is not intended * for use in encrypting large blocks of data or data streams. * * As stated above, this implementation is based on studying existing work * in the public domain or under Open Source (specifically LGPL) license. * The code, however, is written from scratch. Obviously, I make no claim * with regard to those earlier works (except to claim that I am grateful * to the previous implementors whose work I studied). See the list of * references below for resources I used. * * References: * I read through the libmcrypt code to see how they put the pieces * together. See: http://mcrypt.hellug.gr/ * Libmcrypt is available under the terms of the LGPL. * * The libmcrypt implementation includes the following credits: * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted * from the 1977 public-domain program by Jim Gillogly * Modified for additional speed - 6 December 1988 Phil Karn * Modified for parameterized key schedules - Jan 1991 Phil Karn * modified in order to use the libmcrypt API by Nikos Mavroyanopoulos * All modifications are placed under the license of libmcrypt. * * See also Phil Karn's privacy and security page: * http://www.ka9q.net/privacy.html * * I relied heavily upon: * Applied Cryptography, Second Edition: * Protocols, Algorithms, and Source Code in C * by Bruce Schneier. ISBN 0-471-11709-9, John Wiley & Sons, Inc., 1996 * Particularly Chapter 12. * * Here's one more DES resource, which I found quite helpful (aside from * the Clinton jokes): * http://www.aci.net/kalliste/des.htm * Has moved to: * http://orlingrabbe.com/des.htm * * Finally, the use of DES in SMB is covered in: * Implementing CIFS - the Common Internet File System * by your truly. ISBN 0-13-047116-X, Prentice Hall PTR., August 2003 * Section 15.3, in particular. * (Online at: http://ubiqx.org/cifs/SMB.html#SMB.8.3) * * ========================================================================== ** */#include "DES.h"/* -------------------------------------------------------------------------- ** * Static Constants: *//* Initial permutation map. * In the first step of DES, the bits of the initial plaintext are rearranged * according to the map given below. This map and those like it are read by * the Permute() function (below) which uses the maps as a guide when moving * bits from one place to another. * * Note that the values here are all one less than those shown in Schneier. * That's because C likes to start counting from 0, not 1. * * According to Schneier (Ch12, pg 271), the purpose of the initial * permutation was to make it easier to load plaintext and ciphertext into * a DES ecryption chip. I have no idea why that would be the case. */static const uint8_t InitialPermuteMap[64] = { 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6 };/* Key permutation map. * Like the input data and encryption result, the key is permuted before * the algorithm really gets going. The original algorithm called for an * eight-byte key in which each byte contained a parity bit. During the * key permutiation, the parity bits were discarded. The DES algorithm, * as used with SMB, does not make use of the parity bits. Instead, SMB * passes 7-byte keys to DES. For DES implementations that expect parity, * the parity bits must be added. In this case, however, we're just going * to start with a 7-byte (56 bit) key. KeyPermuteMap, below, is adjusted * accordingly and, of course, each entry in the map is reduced by 1 with * respect to the documented values because C likes to start counting from * 0, not 1. */static const uint8_t KeyPermuteMap[56] = { 49, 42, 35, 28, 21, 14, 7, 0, 50, 43, 36, 29, 22, 15, 8, 1, 51, 44, 37, 30, 23, 16, 9, 2, 52, 45, 38, 31, 55, 48, 41, 34, 27, 20, 13, 6, 54, 47, 40, 33, 26, 19, 12, 5, 53, 46, 39, 32, 25, 18, 11, 4, 24, 17, 10, 3, };/* Key rotation table. * At the start of each round of encryption, the key is split and each * 28-bit half is rotated left. The number of bits of rotation per round * is given in the table below. */static const uint8_t KeyRotation[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };/* Key compression table. * This table is used to select 48 of the 56 bits of the key. * The left and right halves of the source text are each 32 bits, * but they are expanded to 48 bits and the results are XOR'd * against the compressed (48-bit) key. */static const uint8_t KeyCompression[48] = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };/* Data expansion table. * This table is used after the data block (64-bits) has been split * into two 32-bit (4-byte) halves (generally denoted L and R). * Each 32-bit half is "expanded", using this table, to a 48 bit * data block, which is then XOR'd with the 48 bit subkey for the * round. */static const uint8_t DataExpansion[48] = { 31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0 };/* The (in)famous S-boxes. * These are used to perform substitutions. * Six bits worth of input will return four bits of output. * The four bit values are stored in these tables. Each table has * 64 entries...and 6 bits provides a number between 0 and 63. * There are eight S-boxes, one per 6 bits of a 48-bit value. * Thus, 48 bits are reduced to 32 bits. Obviously, this step * follows the DataExpansion step. * * Note that the literature generally shows this as 8 arrays each * with four rows and 16 colums. There is a complex formula for * mapping the 6 bit input values to the correct row and column. * I've pre-computed that mapping, and the tables below provide * direct 6-bit input to 4-bit output. See pp 274-274 in Schneier. */static const uint8_t SBox[8][64] = { { /* S0 */ 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1, 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8, 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7, 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13 }, { /* S1 */ 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14, 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5, 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2, 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9 }, { /* S2 */ 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10, 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1, 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7, 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12 }, { /* S3 */ 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3, 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9, 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8, 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14 }, { /* S4 */ 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1, 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6, 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13, 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3 }, { /* S5 */ 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5, 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8, 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10, 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13 }, { /* S6 */ 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10, 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6, 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7, 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12 }, { /* S7 */ 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4, 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2, 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13, 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11 } };/* P-Box permutation. * This permutation is applied to the result of the S-Box Substitutions. * It's a straight-forward re-arrangement of the bits. */static const uint8_t PBox[32] = { 15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24 };/* Final permutation map. * This is supposed to be the inverse of the Initial Permutation, * but there's been a bit of fiddling done. * As always, the values given are one less than those in the literature * (because C starts counting from 0, not 1). In addition, the penultimate * step in DES is to swap the left and right hand sides of the ciphertext. * The inverse of the Initial Permutation is then applied to produce the * final result. * To save a step, the map below does the left/right swap as well as the * inverse permutation. */static const uint8_t FinalPermuteMap[64] = { 7, 39, 15, 47, 23, 55, 31, 63, 6, 38, 14, 46, 22, 54, 30, 62, 5, 37, 13, 45, 21, 53, 29, 61, 4, 36, 12, 44, 20, 52, 28, 60, 3, 35, 11, 43, 19, 51, 27, 59, 2, 34, 10, 42, 18, 50, 26, 58, 1, 33, 9, 41, 17, 49, 25, 57, 0, 32, 8, 40, 16, 48, 24, 56 };/* -------------------------------------------------------------------------- ** * Macros: * * CLRBIT( STR, IDX ) * Input: STR - (uchar *) pointer to an array of 8-bit bytes. * IDX - (int) bitwise index of a bit within the STR array * that is to be cleared (that is, given a value of 0). * Notes: This macro clears a bit within an array of bits (which is * built within an array of bytes). * - The macro converts to an assignment of the form A &= B. * - The string of bytes is viewed as an array of bits, read from * highest order bit first. The highest order bit of a byte * would, therefore, be bit 0 (within that byte). * * SETBIT( STR, IDX ) * Input: STR - (uchar *) pointer to an array of 8-bit bytes. * IDX - (int) bitwise index of a bit within the STR array * that is to be set (that is, given a value of 1). * Notes: This macro sets a bit within an array of bits (which is * built within an array of bytes). * - The macro converts to an assignment of the form A |= B. * - The string of bytes is viewed as an array of bits, read from * highest order bit first. The highest order bit of a byte * would, therefore, be bit 0 (within that byte). * * GETBIT( STR, IDX ) * Input: STR - (uchar *) pointer to an array of 8-bit bytes. * IDX - (int) bit-wise index of a bit within the STR array * that is to be read. * Output: True (1) if the indexed bit was set, else false (0). * * -------------------------------------------------------------------------- ** */#define CLRBIT( STR, IDX ) ( (STR)[(IDX)/8] &= ~(0x01 << (7 - ((IDX)%8))) )#define SETBIT( STR, IDX ) ( (STR)[(IDX)/8] |= (0x01 << (7 - ((IDX)%8))) )#define GETBIT( STR, IDX ) (( ((STR)[(IDX)/8]) >> (7 - ((IDX)%8)) ) & 0x01)/* -------------------------------------------------------------------------- ** * Static Functions: */static void Permute( uchar *dst, const uchar *src, const uint8_t *map, const int mapsize ) /* ------------------------------------------------------------------------ ** * Performs a DES permutation, which re-arranges the bits in an array of * bytes. * * Input: dst - Destination into which to put the re-arranged bits. * src - Source from which to read the bits. * map - Permutation map. * mapsize - Number of bytes represented by the