Wiselib
|
00001 /*************************************************************************** 00002 ** This file is part of the generic algorithm library Wiselib. ** 00003 ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project. ** 00004 ** ** 00005 ** The Wiselib is free software: you can redistribute it and/or modify ** 00006 ** it under the terms of the GNU Lesser General Public License as ** 00007 ** published by the Free Software Foundation, either version 3 of the ** 00008 ** License, or (at your option) any later version. ** 00009 ** ** 00010 ** The Wiselib is distributed in the hope that it will be useful, ** 00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** 00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** 00013 ** GNU Lesser General Public License for more details. ** 00014 ** ** 00015 ** You should have received a copy of the GNU Lesser General Public ** 00016 ** License along with the Wiselib. ** 00017 ** If not, see <http://www.gnu.org/licenses/>. ** 00018 ** ** 00019 ** Author: Christoph Knecht, University of Bern 2010 ** 00020 ***************************************************************************/ 00021 #ifndef DIFFIE_HELLMAN_LIST_H 00022 #define DIFFIE_HELLMAN_LIST_H 00023 00024 #include <stdlib.h> 00025 #include <stdint.h> 00026 #include <stdio.h> 00027 #include <string.h> 00028 #include <time.h> 00029 #include <gmp.h> 00030 #include "algorithm/sha256.h" 00031 #include "algorithm/diffie_hellman_config.h" 00032 #include "util/serialization/simple_types.h" 00033 00034 namespace wiselib 00035 { 00036 class DiffieHellmanList 00037 { 00038 public: 00039 inline DiffieHellmanList(); 00040 inline const uint8_t* key(); 00041 inline uint8_t set_B( const int8_t*, uint8_t ); 00042 inline void set_is_initialized(); 00043 inline void generate_key( mpz_t, mpz_t ); 00044 inline uint8_t is_initialized(); 00045 00046 private: 00047 uint8_t Tmp_c_[ KEY_LENGTH / 8 ]; 00048 00049 // depending on the key-length, max determines the amount of 128 Bytes long messages there were sent 00050 uint8_t max_; 00051 // is_set will be used as a bitmask, therefore we need to determine how many bytes we have to allocate 00052 uint8_t is_set_[ KEY_LENGTH / ( 1024 * 8 ) + 1 ]; 00053 }; 00054 // ---------------------------------------------------------------------- 00055 // ---------------------------------------------------------------------- 00056 // ---------------------------------------------------------------------- 00057 DiffieHellmanList:: 00058 DiffieHellmanList() 00059 { 00060 max_ = KEY_LENGTH / 1024; 00061 memset( Tmp_c_, '\0', KEY_LENGTH / 8 ); 00062 memset( is_set_, '\0', KEY_LENGTH / ( 1024 * 8 ) + 1 ); 00063 } 00064 // ---------------------------------------------------------------------- 00065 // reassembles the public key and generate a big int of it 00066 uint8_t 00067 DiffieHellmanList:: 00068 set_B( const int8_t *payload, uint8_t seq_nr ) 00069 { 00070 // reassembles the key with help of the sequence number 00071 if( seq_nr >= 0 && seq_nr < max_ ) 00072 { 00073 // set the according bit to one and if necessary use the following byte in is_set_ 00074 is_set_[ seq_nr / 8 ] = is_set_[ seq_nr / 8 ] | ( 1 << ( ( seq_nr ) % 8 ) ); 00075 memcpy( &Tmp_c_[ seq_nr * 128 ], payload, 128 ); 00076 } 00077 00078 // checks whether all key parts arrived 00079 uint8_t i; 00080 for( i = 0; i < max_; i++ ) 00081 { 00082 // is every bit set? 00083 if( !( is_set_[ i / 8 ] & ( 1 << ( i % 8 ) ) ) ) 00084 return 0; 00085 } 00086 00087 return 1; 00088 } 00089 // ---------------------------------------------------------------------- 00090 void 00091 DiffieHellmanList:: 00092 set_is_initialized() 00093 { 00094 is_set_[ max_ / 8 ] = is_set_[ max_ / 8 ] | ( 1 << 7 ); 00095 } 00096 // ---------------------------------------------------------------------- 00097 // returns the calculated key in its string form 00098 const uint8_t* 00099 DiffieHellmanList:: 00100 key() 00101 { 00102 return (const uint8_t*)Tmp_c_; 00103 } 00104 // ---------------------------------------------------------------------- 00105 // generates the key according to Diffie-Hellman RFC - the resulting sha256 key 00106 // will be written into Tmp_c_ 00107 void 00108 DiffieHellmanList:: 00109 generate_key( mpz_t a, mpz_t p ) 00110 { 00111 // the big integeger (gmplib) 00112 mpz_t K; 00113 mpz_init2( K, KEY_LENGTH ); 00114 mpz_import( K, KEY_LENGTH / 8, 1, 1, 0, 0, Tmp_c_ ); 00115 00116 mpz_powm( K, K, a, p ); 00117 memset( Tmp_c_, '\0', KEY_LENGTH / 8 ); 00118 mpz_export( Tmp_c_, NULL, 1, 1, 0, 0, K ); 00119 00120 Sha256 sha256_; 00121 sha256_.reset(); 00122 sha256_.update( Tmp_c_, 3 ); 00123 memset( Tmp_c_, '\0', KEY_LENGTH / 8 ); 00124 sha256_.finish( Tmp_c_ ); 00125 } 00126 // ---------------------------------------------------------------------- 00127 // the highest bit in is_set_ checks whether this list entry has been initalized 00128 uint8_t 00129 DiffieHellmanList:: 00130 is_initialized() 00131 { 00132 return is_set_[ max_ / 8 ] & ( 1 << 7 ); 00133 } 00134 } 00135 00136 #endif