Wiselib
wiselib.testing/algorithms/cluster/securehdlcluster/securehdlclustering.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines