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 00020 #ifndef __ALGORITHMS_SECURE_HDL_CLUSTERING_H_ 00021 #define __ALGORITHMS_SECURE_HDL_CLUSTERING_H_ 00022 00023 #include "securehdlclusteringtypes.h" 00024 #include "securehdlclusteringmessage.h" 00025 #include "algorithms/crypto/sha1.h" 00026 00027 #include <iostream> 00028 00029 namespace wiselib { 00030 00031 class HKC { 00032 public: 00033 static bool equal(const HKCelement_t& a, const HKCelement_t& b) { 00034 for (int i = 0; i < HKC_ELEMENT_SIZE; i++) { 00035 if(a.A[i]!=b.A[i]) return false; 00036 } 00037 return true; 00038 } 00039 static HKCelement_t zero_element() { 00040 HKCelement_t ret; 00041 for (int i = 0; i < HKC_ELEMENT_SIZE; i++) ret.A[i]=0; 00042 return ret; 00043 } 00044 static HKCelement_t secure_one_way_key_function(const HKCelement_t& input) { 00045 HKCelement_t ret; 00046 //perform sHA1 on the input 00047 SHA1Context sha; 00048 SHA1::SHA1Reset(&sha); 00049 SHA1::SHA1Update(&sha, input.A, 20 ); 00050 SHA1::SHA1Digest(&sha, ret.A); 00051 return ret; 00052 } 00053 static bool check_authenticity(const HKCelement_t& input, const HKCelement_t& my_element, uint8_t times) { 00054 HKCelement_t temp=input; 00055 for(int i=0; i<times; i++) temp=secure_one_way_key_function(temp); 00056 std::cout<<"comparing "; 00057 for(int i=0; i<20; i++) printf("%2x", temp.A[i]); 00058 std::cout<<" with "; 00059 for(int i=0; i<20; i++) printf("%2x", my_element.A[i]); 00060 std::cout<<std::endl; 00061 if(equal(temp, my_element)) return true; 00062 else return false; 00063 } 00064 00065 // --------------- initial key generation -------------------------------------------- 00066 00067 static HKCelement_t random_HKC_element() { 00068 return zero_element(); 00069 } 00070 static HKCelement_t* generate_HKC(HKCelement_t& input, uint8_t size) { 00071 HKCelement_t* ret=new HKCelement_t[size]; 00072 //place input (the last key of chain) at the end of the chain 00073 HKCelement_t temp; 00074 for (int i = 0; i < HKC_ELEMENT_SIZE; i++) temp.A[i]=input.A[i]; 00075 for (int j = 0; j < HKC_ELEMENT_SIZE; j++) ret[size-1].A[j]=temp.A[j]; 00076 00077 //generate rest of the key chain and store it on ret 00078 for (int k = size-2; k >= 0; k--) { 00079 temp=secure_one_way_key_function(temp); 00080 for (int l = 0; l < HKC_ELEMENT_SIZE; l++) ret[k].A[l]=temp.A[l]; 00081 } 00082 return ret; 00083 } 00084 }; 00085 00093 template<typename OsModel_P, 00094 typename Radio_P = typename OsModel_P::Radio, 00095 typename Timer_P = typename OsModel_P::Timer> 00096 class SecureHdlClustering { 00097 00098 public: 00099 00100 typedef int cluster_id_t; 00101 typedef uint8_t cluster_level_t; //quite useless within current scheme, supported for compatibility issues 00102 typedef OsModel_P OsModel; 00103 typedef Radio_P Radio; 00104 typedef Timer_P Timer; 00105 00106 typedef SecureHdlClustering<OsModel_P, Radio_P, Timer_P> self_t; 00107 00108 typedef typename Radio::node_id_t node_id_t; 00109 typedef typename Radio::size_t size_t; 00110 typedef typename Radio::block_data_t block_data_t; 00111 00112 typedef SecureHdlMessage<OsModel, Radio> SHdlMessage; 00113 00114 typedef delegate1<void, int> cluster_delegate_t; 00115 00116 //quite useless within current scheme, supported for compatibility issues 00117 enum EventIds { 00118 CLUSTER_HEAD_CHANGED = 0, 00119 NODE_JOINED = 1, 00120 NODE_LEFT = 2 00121 }; 00122 00123 //quite useless within current scheme, supported for compatibility issues 00124 enum ClusterIds { 00125 UNKNOWN_CLUSTER_HEAD = 0 00126 }; 00127 00128 void enable( void ); 00129 void disable( void ); 00130 00131 //same as original get_hdl() 00132 inline cluster_id_t cluster_id( cluster_level_t ) { return HDL_; } 00133 00134 //quite useless within current scheme, supported for compatibility issues 00135 inline cluster_level_t cluster_level() { return 0; } 00136 00137 template<class T, void (T::*TMethod)(int)> 00138 inline int reg_changed_callback( T *obj_pnt ) { 00139 state_changed_callback_=cluster_delegate_t::from_method<T, TMethod>( obj_pnt ); 00140 } 00141 inline void unreg_changed_callback( int idx ) { 00142 state_changed_callback_=cluster_delegate_t(); 00143 } 00144 00145 inline void set_sink( bool sink) { sink_ = sink; } 00146 00147 inline void set_chain(HKCelement_t *input, uint8_t size) { 00148 if(!sink_) return; 00149 chain_=new HKCelement_t[size]; 00150 chain_size=size; 00151 memcpy(chain_, input, size*sizeof(HKCelement_t)); 00152 } 00153 inline void set_chain_element(const HKCelement_t& input) { 00154 k0_=input; 00155 } 00156 00159 SecureHdlClustering(): 00160 sink_(false), 00161 HDL_(-1), 00162 flag(true) 00163 {}; 00164 ~SecureHdlClustering() {}; 00166 00167 protected: 00168 void receive(node_id_t from, size_t len, block_data_t* data); 00169 void timer_expired(void*); 00170 00171 private: 00172 Radio& radio() 00173 { return *radio_; } 00174 00175 Timer& timer() 00176 { return *timer_; } 00177 00178 Radio * radio_; 00179 Timer * timer_; 00180 00181 bool sink_, flag; 00182 cluster_id_t HDL_; 00183 int callback_id_; 00184 cluster_delegate_t state_changed_callback_; 00185 HKCelement_t *chain_, k0_; 00186 int chain_size, current_layer_, time_slice_, time_step; 00187 00188 }; 00189 00190 template<typename OsModel_P, 00191 typename Radio_P, 00192 typename Timer_P> 00193 void 00194 SecureHdlClustering<OsModel_P, Radio_P, Timer_P>:: 00195 enable( void ) { 00196 time_slice_=time_step=2000; //1334 00197 Radio_P::enable_radio(); 00198 callback_id_ = Radio_P::template reg_recv_callback<self_t, 00199 &self_t::receive>(this ); 00200 current_layer_=1; 00201 if(sink_) { 00202 //I am sink, bcast first message with HDL=0 00203 HDL_=0; 00204 SHdlMessage msg; 00205 msg.set_current_layer(current_layer_); 00206 msg.set_key(&chain_[current_layer_]); 00207 std::cout<<"Sink signs with : "; 00208 for(int i=0;i<20;i++) printf("%2x", msg.key()->A[i]); 00209 std::cout<<std::endl; 00210 radio().send(radio().BROADCAST_ADDRESS, msg.buffer_size(), (block_data_t*) &msg); 00211 } else { 00212 HDL_=-1; 00213 } 00214 timer().template set_timer<self_t, 00215 &self_t::timer_expired>(time_slice_, this, (void*) 0); 00216 } 00217 00218 template<typename OsModel_P, 00219 typename Radio_P, 00220 typename Timer_P> 00221 void 00222 SecureHdlClustering<OsModel_P, Radio_P, Timer_P>:: 00223 disable( void ) { 00224 Radio_P::unreg_recv_callback(callback_id_ ); 00225 Radio_P::disable(); 00226 } 00227 00228 template<typename OsModel_P, 00229 typename Radio_P, 00230 typename Timer_P> 00231 void 00232 SecureHdlClustering<OsModel_P, Radio_P, Timer_P>:: 00233 receive(node_id_t from, size_t len, block_data_t* data) { 00234 00235 if ( from == radio().id( ) ) return; 00236 00237 SHdlMessage *msg=(SHdlMessage*) data; 00238 if(HDL_==-1) { 00239 std::cout<<"Node "<<radio().id()<<" gets "; 00240 for(int i=0;i<20;i++) printf("%2x", msg->key()->A[i]); 00241 std::cout<<std::endl; 00242 putchar('\n'); 00243 if((current_layer_==msg->current_layer()) && (HKC::check_authenticity(*(msg->key()), k0_, current_layer_))) { 00244 HDL_=msg->current_layer(); 00245 state_changed_callback_(NODE_JOINED); 00246 } 00247 } else if((flag) && (msg->current_layer()>HDL_)) { 00248 flag=false; 00249 Radio_P::send(Radio_P::BROADCAST_ADDRESS, msg->buffer_size(), data); 00250 } 00251 00252 } 00253 00254 template<typename OsModel_P, 00255 typename Radio_P, 00256 typename Timer_P> 00257 void 00258 SecureHdlClustering<OsModel_P, Radio_P, Timer_P>:: 00259 timer_expired(void *data) { 00260 current_layer_++; 00261 time_slice_+=time_step; 00262 flag=true; 00263 if(sink_){ 00264 if(current_layer_>=chain_size) return; 00265 SHdlMessage msg; 00266 msg.set_current_layer(current_layer_); 00267 msg.set_key(&chain_[current_layer_]); 00268 std::cout<<"Sink signs with : "; 00269 for(int i=0;i<20;i++) printf("%2x", msg.key()->A[i]); 00270 std::cout<<std::endl; 00271 radio().send(radio().BROADCAST_ADDRESS, msg.buffer_size(), (block_data_t*) &msg); 00272 } 00273 timer().template set_timer<self_t, 00274 &self_t::timer_expired>(time_slice_, this, (void*) 0); 00275 } 00276 00277 } 00278 00279 #endif