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 /* 00021 * @brief This class implements HARPS a key distribution scheme based on on symmetric crypto primitives 00022 * for more information see http://eprint.iacr.org/2003/170.pdf 00023 */ 00024 00025 #ifndef __ALGORITHMS_CRYPTO_HARPS_H__ 00026 #define __ALGORITHMS_CRYPTO_HARPS_H__ 00027 00028 //#include "sha1.h" 00029 #include <string.h> 00030 00031 #include "harpsutils.h" 00032 00033 00034 00035 00036 namespace wiselib { 00049 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00050 class HARPS { 00051 public: 00052 00053 00054 00055 typedef OsModel_P OsModel; 00056 typedef Radio_P Radio; 00057 typedef Debug_P Debug; 00058 00059 typedef KeyPool_P KeyPool; 00060 typedef HashAlgo_P HashAlgo; 00061 00062 00063 typedef typename Radio::node_id_t node_id_t; //int 00064 00065 typedef typename Radio::size_t size_t; //long 00066 typedef typename Radio::block_data_t block_data_t;//unsigned char 00067 00068 typedef wiselib::HARPSUTILS<HashAlgo> HarpsUtils; 00069 00070 00071 00072 00073 00074 00077 HARPS(); 00078 ~HARPS(); 00080 00083 void enable( void ); 00084 void disable( void ); 00086 00087 00088 00089 //initialize keys 00090 00091 bool key_setup(node_id_t comPartner_ID, uint8_t* sessionKey, KeyPool pool); 00092 00093 00094 00095 00096 00097 00098 00099 00100 private: 00101 00102 00103 //KeyPool keypool; 00104 00105 Debug* debug_; 00106 00107 00108 //methods 00109 00110 void createHarpsPublicKey(uint16_t nodeId, struct HarpsUtils::HarpsPublicKey* pubKey); 00111 int createHarpsSharedKey(uint8_t* sessionKey, KeyPool pool, struct HarpsUtils::HarpsPublicKey* foreignKey); 00112 00113 00114 void srand(uint32_t new_seed); 00115 //uint32 randomValue_; 00116 uint32_t randomValue1_; 00117 uint32_t randomValue2_; 00118 00119 00120 00121 00122 00123 }; 00124 00125 // ----------------------------------------------------------------------- 00126 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00127 HARPS<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00128 HARPS() 00129 { 00130 00131 00132 } 00133 00134 // ----------------------------------------------------------------------- 00135 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00136 HARPS<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00137 ~HARPS() 00138 { 00139 } 00140 00141 // ----------------------------------------------------------------------- 00142 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00143 void 00144 HARPS<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00145 enable( void ) 00146 { 00147 00148 00149 } 00150 00151 // ----------------------------------------------------------------------- 00152 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00153 void 00154 HARPS<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00155 disable( void ) 00156 { 00157 } 00158 // ----------------------------------------------------------------------- 00159 00160 00161 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00162 bool 00163 HARPS<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00164 key_setup(node_id_t comPartner, uint8_t* sessionKey, KeyPool pool) 00165 { 00166 00167 00168 00169 struct HarpsUtils::HarpsPublicKey foreignKey[keyPoolSize] = {{0}}; 00170 //generate the foreign public key of the communication partner 00171 createHarpsPublicKey((uint16_t)comPartner, foreignKey); 00172 00173 #ifdef DEBUG_L1 00174 debug_->debug("Foreign key for partner %x",comPartner); 00175 for(uint16_t i = 0 ; i< keyPoolSize; i++) 00176 debug_->debug("fk[%d].id=%d - fk[%d].depth=%d",i,foreignKey[i].keyId,i,foreignKey[i].hashDepth); 00177 #endif 00178 00179 //generate shared key with communication partner 00180 createHarpsSharedKey(sessionKey, pool, foreignKey); 00181 00182 00183 00184 return true; 00185 00186 } 00187 00188 // ----------------------------------------------------------------------- 00189 00190 // ----------------------------------------------------------------------- 00191 /* 00192 * @Brief Create the public key tuple (keyID, HashDepth) for a given NodeID, please note that the random function returns the same value for the same srand parameter 00193 * @param nodeId the communication partner ID 00194 * @param pubKey out array contains tuples of public keys of the communication partner (keyID, hashdepth) 00195 */ 00196 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00197 void 00198 HARPS<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00199 createHarpsPublicKey(uint16_t commPartnerId, struct HarpsUtils::HarpsPublicKey* commPartnerPubKey ) { 00200 00201 //1. Generate Public key 00202 00203 int shift = 0xfe45; 00204 00205 srand((uint16_t)(commPartnerId+shift)); 00206 00207 for(uint8_t i = 0; i < keyPoolSize; i++) { 00208 //commPartnerPubKey[i].keyId = (uint16_t)HARPSUTILS::rand((uint16_t)taPoolSize,&randomValue_); 00209 //commPartnerPubKey[i].hashDepth = (uint8_t)HARPSUTILS::rand(maxHashDepth,&randomValue_); 00210 commPartnerPubKey[i].keyId = (uint16_t)HarpsUtils::rand((uint16_t)taPoolSize,&randomValue1_,&randomValue2_); 00211 commPartnerPubKey[i].hashDepth = (uint8_t)HarpsUtils::rand(maxHashDepth,&randomValue1_,&randomValue2_); 00212 00213 //check if the key id already exists in the nodes public key 00214 for(uint8_t j = 0; j < i; j++) { 00215 //if key id already exists then skip it 00216 if(commPartnerPubKey[i].keyId == commPartnerPubKey[j].keyId) { 00217 i--; 00218 break; 00219 } 00220 } 00221 } 00222 00223 00224 00225 //Sorting 00226 HarpsUtils::quicksort(commPartnerPubKey, 0, (uint16_t)keyPoolSize - 1); 00227 00228 } 00229 // ----------------------------------------------------------------------- 00230 /* 00231 *@brief create the session key with the communication partner 00232 *@param sessionKey out the session key 00233 */ 00234 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00235 int 00236 HARPS<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00237 createHarpsSharedKey(uint8_t* sessionKey, KeyPool pool, struct HarpsUtils::HarpsPublicKey* foreignKey) { 00238 00239 uint8_t curSharedKey[KEY_LENGTH] = {0}; 00240 uint8_t tmpSessionKey[KEY_LENGTH] = {0}; 00241 00242 uint8_t hashKey[KEY_LENGTH] = {0x85,0x98,0x17,0x00,0xfd,0x9d,0xaa,0x11,0x97,0x41,0xa7,0x5b,0xc0,0x82,0x55,0x93}; 00243 00244 memset(sessionKey,0,KEY_LENGTH); 00245 00246 uint16_t i = 0; 00247 uint16_t j = 0; 00248 00249 00250 struct HarpsUtils::HarpsKey key; 00251 00252 while(i < keyPoolSize && j < keyPoolSize) { 00253 00254 //*key = keypool.at(i); 00255 00256 00257 00258 key= ((struct HarpsUtils::HarpsKey*)pool)[i]; 00259 00260 00261 00262 #ifdef DEBUG_L2 00263 00264 debug_->debug("test Key TA-ID %d with hashdepth: %d (Position in own keypool: %d)", key.pubKey.keyId, key.pubKey.hashDepth, i); 00265 #endif 00266 if(key.pubKey.keyId < foreignKey[j].keyId) { 00267 i++; 00268 00269 } 00270 else if(key.pubKey.keyId > foreignKey[j].keyId) { 00271 j++; 00272 } 00273 else if(key.pubKey.keyId == foreignKey[j].keyId) { 00274 00275 00276 00277 memcpy(curSharedKey, key.hashedKey, KEY_LENGTH); 00278 00279 00280 00281 00282 00283 00284 00285 #ifdef DEBUG_L2 00286 00287 debug_->debug("Chosen Key has TA-ID %d with hashdepth: %d (Position in keypool: %d)", foreignKey[j].keyId, foreignKey[j].hashDepth, i); 00288 #endif 00289 00290 00291 00292 00293 if(key.pubKey.hashDepth < foreignKey[j].hashDepth) { 00294 00295 00296 00297 #ifdef DEBUG_L2 00298 00299 debug_->debug("Chosen Key has TA-ID %d with hashdepth: %d hash", foreignKey[j].keyId, foreignKey[j].hashDepth); 00300 00301 for(uint8_t k=0 ; k < KEY_LENGTH; k++){ 00302 debug_->debug("OKey [%d] = %d ", k, key.hashedKey[k]); 00303 } 00304 00305 #endif 00306 00307 uint8_t additionalHash = foreignKey[j].hashDepth - key.pubKey.hashDepth; 00308 00309 uint8_t k = 0; 00310 00311 for(k = 0; k < additionalHash; k++) { 00312 00313 00314 00315 //input curSharedKey 00316 //output &tmpSessionKey[16] 00317 //key hashkey 00318 //SHA1::hmac_sha1(input,input_len,Key,Key_len,output); 00319 00320 //before refactoring 00321 //SHA1::hmac_sha1(curSharedKey,KEY_LENGTH,hashKey,KEY_LENGTH,tmpSessionKey); 00322 //after refactoring 00323 HarpsUtils::hash(curSharedKey,KEY_LENGTH,hashKey,KEY_LENGTH,tmpSessionKey); 00324 00325 memcpy(curSharedKey, tmpSessionKey, KEY_LENGTH); 00326 00327 00328 } 00329 00330 00331 } 00332 else { 00333 00334 00335 memcpy(tmpSessionKey, curSharedKey, KEY_LENGTH); 00336 00337 00338 } 00339 00340 for(uint8_t kk = 0 ; kk < KEY_LENGTH ; kk++){ 00341 curSharedKey[kk]^=sessionKey[kk]; 00342 } 00343 00344 memcpy(tmpSessionKey, curSharedKey, KEY_LENGTH); 00345 00346 //hash(2*keySize - 1, (uint8*)tmpSessionKey, keySize, (uint8*)sessionKey, 1); 00347 00348 //input &tmpSessionKey[KEY_LENGTH] 00349 //output sessionkey 00350 //key &tmpSessionKey[0] 00351 00352 //SHA1::hmac_sha1(input,input_len,Key,Key_len,output); 00353 #ifdef DEBUG_L2 00354 debug_->debug("Key %d -%d before final hash", key.pubKey.keyId, key.pubKey.hashDepth); 00355 for(uint8_t k=0 ; k < KEY_LENGTH; k++){ 00356 debug_->debug("Key [%d] = %x ", k, tmpSessionKey[k]); 00357 } 00358 00359 #endif 00360 00361 uint8_t tem [KEY_LENGTH]= {0}; 00362 uint8_t tem2 [KEY_LENGTH]= {0}; 00363 memcpy(tem,tmpSessionKey,KEY_LENGTH); 00364 //before refactoring 00365 //SHA1::hmac_sha1(tem,KEY_LENGTH,hashKey,KEY_LENGTH,tem2); 00366 //after refactoring 00367 HarpsUtils::hash(tem,KEY_LENGTH,hashKey,KEY_LENGTH,tem2); 00368 00369 00370 memcpy(tmpSessionKey, tem2, KEY_LENGTH); 00371 memcpy(sessionKey, tem2, KEY_LENGTH); 00372 /*original 00373 //SHA1::hmac_sha1(tmpSessionKey,KEY_LENGTH,hashKey,KEY_LENGTH,sessionKey); 00374 //memcpy(tmpSessionKey, sessionKey, KEY_LENGTH); 00375 end original*/ 00376 /*funk 00377 memcpy(sessionKey,tmpSessionKey ,KEY_LENGTH); 00378 endfunk*/ 00379 00380 #ifdef DEBUG_L2 00381 debug_->debug("Key %d -%d after final hash", key.pubKey.keyId, key.pubKey.hashDepth); 00382 for(uint8_t k=0 ; k < KEY_LENGTH; k++){ 00383 debug_->debug("SKey [%d] = %x ", k, sessionKey[k]); 00384 } 00385 00386 #endif 00387 #ifdef DEBUG_L6 00388 debug_->debug("Key %d -%d after final hash", key.pubKey.keyId, key.pubKey.hashDepth); 00389 char target[2*16+1] = {0}; 00390 char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 00391 for(int jj = 0; j < 16; j++){ 00392 target[jj*2] = hexval[((sessionKey[jj] >> 4) & 0xF)]; 00393 target[(jj*2) + 1] = hexval[(sessionKey[jj]) & 0x0F]; 00394 } 00395 target[2*16]='\0'; 00396 00397 00398 00399 debug_->debug("%s",target); 00400 #endif 00401 00402 00403 i++; 00404 j++; 00405 00406 00407 } 00408 00409 00410 } 00411 00412 00413 return 0; 00414 } 00415 00416 // ----------------------------------------------------------------------- 00417 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00418 void 00419 HARPS<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00420 srand(uint32_t new_seed) { 00421 //randomValue_ = new_seed; 00422 randomValue1_ = new_seed-3; 00423 randomValue2_ = new_seed+7; 00424 } 00425 00426 00427 // ----------------------------------------------------------------------- 00428 00429 00430 // ----------------------------------------------------------------------- 00431 00432 00433 } 00434 #endif