/* Copyright ©2001 e-business technology, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License Version 2, as published by the Free Software Foundation. This program 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. The program may contain errors that could cause failures or loss of data, and may be incomplete or contain inaccuracies. By using the program, you expressly acknowledge and agree that use of the program, or any portion thereof, is at your sole and entire risk. You are solely responsible for determining the appropriateness of using, copying, distributing and modifying the program and assume all risks of exercising your rights under the license, compliance with all applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES DO NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM, THAT THE FUNCTIONS CONTAINED IN THE PROGRAM WILL MEET YOUR NEEDS, THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE PROGRAM WILL BE CORRECTED. THE DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THE LICENSE TO USE THE PROGRAM AND NO USE OF THE PROGRAM IS AUTHORIZED EXCEPT UNDER THE DISCLAIMER. ALSO, SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. See the GNU General Public License Version 2 for more details. You should have received a copy of the GNU General Public License Version 2 along with this program; if not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "diffie.h" // generate a seed number that is reasonably random void rngSimple::randomSeed( ) { int i; union { DWORD seedval[4]; SYSTEMTIME st; ULARGE_INTEGER ularge[3]; MEMORYSTATUS ms; }; // get some non-constant values from the system and mix them into the pool seedpool[0] ^= (DWORD)GetClipboardOwner(); seedpool[1] ^= (DWORD)GetCurrentProcess(); seedpool[2] ^= (DWORD)GetCurrentProcessId(); seedpool[3] ^= (DWORD)GetCurrentThread(); md5simple( ); seedpool[0] ^= (DWORD)GetCurrentThreadId(); seedpool[1] ^= (DWORD)GetDesktopWindow(); seedpool[2] ^= (DWORD)GetProcessHeap(); seedpool[3] ^= (DWORD)GetTickCount(); md5simple( ); GlobalMemoryStatus( &ms ); seedpool[0] ^= ms.dwMemoryLoad; seedpool[1] ^= ms.dwAvailPhys; seedpool[2] ^= ms.dwAvailPageFile; seedpool[3] ^= ms.dwAvailVirtual; md5simple( ); GetDiskFreeSpaceEx( NULL, &ularge[0], &ularge[2], &ularge[1] ); for( i = 0; i < 4; i++ ) seedpool[i] ^= seedval[i]; md5simple( ); GetSystemTime( &st ); for( i = 0; i < 4; i++ ) seedpool[i] ^= seedval[i]; md5simple( ); } BYTE rngSimple::GenerateByte( ) { md5simple( ); return *(BYTE*)seedpool; } // md5simple - modified from Colin Plumb's public domain md5.c // This version is non-iterative, and only hashes four 32-bit words. void rngSimple::md5simple( ) { #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) // This is the central step in the MD5 algorithm. #define MD5STEP(f,w,x,y,z,in,s) (w += f(x,y,z) + in, w = (w<>(32-s)) + x) DWORD a = 0x67452301; DWORD b = 0xefcdab89; DWORD c = 0x98badcfe; DWORD d = 0x10325476; MD5STEP( F1, a, b, c, d, seedpool[0] + 0xd76aa478, 7 ); MD5STEP( F1, d, a, b, c, seedpool[1] + 0xe8c7b756, 12 ); MD5STEP( F1, c, d, a, b, seedpool[2] + 0x242070db, 17 ); MD5STEP( F1, b, c, d, a, seedpool[3] + 0xc1bdceee, 22 ); MD5STEP( F1, a, b, c, d, 0xf57c0faf, 7 ); MD5STEP( F1, d, a, b, c, 0x4787c62a, 12 ); MD5STEP( F1, c, d, a, b, 0xa8304613, 17 ); MD5STEP( F1, b, c, d, a, 0xfd469501, 22 ); MD5STEP( F1, a, b, c, d, 0x698098d8, 7 ); MD5STEP( F1, d, a, b, c, 0x8b44f7af, 12 ); MD5STEP( F1, c, d, a, b, 0xffff5bb1, 17 ); MD5STEP( F1, b, c, d, a, 0x895cd7be, 22 ); MD5STEP( F1, a, b, c, d, 0x6b901122, 7 ); MD5STEP( F1, d, a, b, c, 0xfd987193, 12 ); MD5STEP( F1, c, d, a, b, 0xa679438e, 17 ); MD5STEP( F1, b, c, d, a, 0x49b40821, 22 ); MD5STEP( F2, a, b, c, d, seedpool[1] + 0xf61e2562, 5 ); MD5STEP( F2, d, a, b, c, 0xc040b340, 9 ); MD5STEP( F2, c, d, a, b, 0x265e5a51, 14 ); MD5STEP( F2, b, c, d, a, seedpool[0] + 0xe9b6c7aa, 20 ); MD5STEP( F2, a, b, c, d, 0xd62f105d, 5 ); MD5STEP( F2, d, a, b, c, 0x02441453, 9 ); MD5STEP( F2, c, d, a, b, 0xd8a1e681, 14 ); MD5STEP( F2, b, c, d, a, 0xe7d3fbc8, 20 ); MD5STEP( F2, a, b, c, d, 0x21e1cde6, 5 ); MD5STEP( F2, d, a, b, c, 0xc33707d6, 9 ); MD5STEP( F2, c, d, a, b, seedpool[3] + 0xf4d50d87, 14 ); MD5STEP( F2, b, c, d, a, 0x455a14ed, 20 ); MD5STEP( F2, a, b, c, d, 0xa9e3e905, 5 ); MD5STEP( F2, d, a, b, c, seedpool[2] + 0xfcefa3f8, 9 ); MD5STEP( F2, c, d, a, b, 0x676f02d9, 14 ); MD5STEP( F2, b, c, d, a, 0x8d2a4c8a, 20 ); MD5STEP( F3, a, b, c, d, 0xfffa3942, 4 ); MD5STEP( F3, d, a, b, c, 0x8771f681, 11 ); MD5STEP( F3, c, d, a, b, 0x6d9d6122, 16 ); MD5STEP( F3, b, c, d, a, 0xfde5380c, 23 ); MD5STEP( F3, a, b, c, d, seedpool[1] + 0xa4beea44, 4 ); MD5STEP( F3, d, a, b, c, 0x4bdecfa9, 11 ); MD5STEP( F3, c, d, a, b, 0xf6bb4b60, 16 ); MD5STEP( F3, b, c, d, a, 0xbebfbc70, 23 ); MD5STEP( F3, a, b, c, d, 0x289b7ec6, 4 ); MD5STEP( F3, d, a, b, c, seedpool[0] + 0xeaa127fa, 11 ); MD5STEP( F3, c, d, a, b, seedpool[3] + 0xd4ef3085, 16 ); MD5STEP( F3, b, c, d, a, 0x04881d05, 23 ); MD5STEP( F3, a, b, c, d, 0xd9d4d039, 4 ); MD5STEP( F3, d, a, b, c, 0xe6db99e5, 11 ); MD5STEP( F3, c, d, a, b, 0x1fa27cf8, 16 ); MD5STEP( F3, b, c, d, a, seedpool[2] + 0xc4ac5665, 23 ); MD5STEP( F4, a, b, c, d, seedpool[0] + 0xf4292244, 6 ); MD5STEP( F4, d, a, b, c, 0x432aff97, 10 ); MD5STEP( F4, c, d, a, b, 0xab9423a7, 15 ); MD5STEP( F4, b, c, d, a, 0xfc93a039, 21 ); MD5STEP( F4, a, b, c, d, 0x655b59c3, 6 ); MD5STEP( F4, d, a, b, c, seedpool[3] + 0x8f0ccc92, 10 ); MD5STEP( F4, c, d, a, b, 0xffeff47d, 15 ); MD5STEP( F4, b, c, d, a, seedpool[1] + 0x85845dd1, 21 ); MD5STEP( F4, a, b, c, d, 0x6fa87e4f, 6 ); MD5STEP( F4, d, a, b, c, 0xfe2ce6e0, 10 ); MD5STEP( F4, c, d, a, b, 0xa3014314, 15 ); MD5STEP( F4, b, c, d, a, 0x4e0811a1, 21 ); MD5STEP( F4, a, b, c, d, 0xf7537e82, 6 ); MD5STEP( F4, d, a, b, c, 0xbd3af235, 10 ); MD5STEP( F4, c, d, a, b, seedpool[2] + 0x2ad7d2bb, 15 ); MD5STEP( F4, b, c, d, a, 0xeb86d391, 21 ); seedpool[0] = a; seedpool[1] = b; seedpool[2] = c; seedpool[3] = d; } diffie512::diffie512() : DH( Integer( ucPrime, KEY_BYTES ), Integer( 2L ) ) { keyed = agreed = FALSE; } BYTE* diffie512::getPublicKey() { if( !keyed ) { keyed = TRUE; GenerateKeyPair( rng, skey, pkey ); } return pkey; } BYTE* diffie512::getMutualKey( BYTE* remoteKey ) { if( !agreed && !remoteKey ) return NULL; if( !keyed ) getPublicKey(); if( !agreed ) { agreed = TRUE; Agree( mkey, skey, remoteKey ); } return mkey; } // 512-bit prime number used for Diffie-Hellman key generation BYTE diffie512::ucPrime[KEY_BYTES] = { 0x84, 0xbd, 0x6a, 0x60, 0xee, 0x88, 0xf1, 0x17, 0x83, 0xbd, 0x4c, 0x30, 0x0f, 0xa4, 0xbf, 0x18, 0xed, 0x65, 0xa8, 0xdd, 0x51, 0x50, 0x20, 0xae, 0x54, 0x73, 0xe4, 0x98, 0x5e, 0x5d, 0xb3, 0x27, 0xed, 0xa3, 0x3b, 0xc9, 0x6d, 0xe9, 0x4e, 0x89, 0x98, 0x73, 0x39, 0x04, 0x47, 0xa7, 0xd4, 0xa5, 0x30, 0x02, 0xd8, 0xa3, 0x5c, 0x43, 0x1b, 0x6a, 0x7c, 0x5d, 0x46, 0x40, 0x66, 0x05, 0x3d, 0x7f };