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_HARPSKEYPOOLGENERATOR_H__ 00026 #define __ALGORITHMS_CRYPTO_HARPSKEYPOOLGENERATOR_H__ 00027 00028 #include "sha1.h" 00029 00030 #include <string.h> 00031 00032 #include "harpsutils.h" 00033 00034 00035 00036 namespace wiselib { 00037 00038 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00039 class HARPSKEYPOOLGENERATOR { 00040 public: 00041 typedef OsModel_P OsModel; 00042 typedef Radio_P Radio; 00043 typedef Debug_P Debug; 00044 00045 typedef KeyPool_P KeyPool; 00046 typedef HashAlgo_P HashAlgo; 00047 00048 00049 00050 typedef typename Radio::node_id_t node_id_t; //int 00051 typedef typename Radio::size_t size_t; //long 00052 typedef typename Radio::block_data_t block_data_t;//unsigned char 00053 00054 typedef wiselib::HARPSUTILS<HashAlgo> HarpsUtils; 00055 00056 00057 00058 00059 00060 #define TA_SECRET_RANDOM_VALUE 1234 00061 #define MAX_BYTE_VALUE 256 00062 00063 00064 00067 HARPSKEYPOOLGENERATOR(); 00068 ~HARPSKEYPOOLGENERATOR(); 00070 00073 void enable( void ); 00074 void disable( void ); 00076 00077 00078 //initialize keys 00079 00080 00081 00082 uint8_t generateKeyPool(node_id_t id, KeyPool keypool); 00083 00084 00085 00086 00087 00088 00089 private: 00090 00091 00092 00093 Debug* debug_; 00094 00095 struct HarpsUtils::HarpsPublicKey publicKey[keyPoolSize]; 00096 struct HarpsUtils::HarpsPublicKey foreignKey[keyPoolSize]; 00097 00098 00099 00100 uint32_t randomValue_; 00101 uint32_t randomValue1_; 00102 uint32_t randomValue2_; 00103 00104 //methods 00105 00106 void createHarpsPublicKey(uint16_t nodeId, struct HarpsUtils::HarpsPublicKey* pubKey); 00107 00108 00109 00110 void srand(uint32_t new_seed); 00111 uint32_t rand(uint32_t upper_bound); 00112 00113 00114 }; 00115 00116 // ----------------------------------------------------------------------- 00117 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00118 HARPSKEYPOOLGENERATOR<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00119 HARPSKEYPOOLGENERATOR() 00120 { 00121 00122 //get self public keys 00123 //createHarpsPublicKey(id, publicKey); 00124 } 00125 00126 // ----------------------------------------------------------------------- 00127 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00128 HARPSKEYPOOLGENERATOR<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00129 ~HARPSKEYPOOLGENERATOR() 00130 { 00131 } 00132 00133 // ----------------------------------------------------------------------- 00134 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00135 void 00136 HARPSKEYPOOLGENERATOR<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00137 enable( void ) 00138 { 00139 00140 00141 } 00142 00143 // ----------------------------------------------------------------------- 00144 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00145 void 00146 HARPSKEYPOOLGENERATOR<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00147 disable( void ) 00148 { 00149 } 00150 // ----------------------------------------------------------------------- 00151 00152 00153 /* 00154 * @Brief Creates the TA original keys and then creates hashed key from them for every public key and stores them in the FLASH. This function should be called in the deployment phase 00155 * @return error code 00156 */ 00157 00158 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00159 uint8_t 00160 HARPSKEYPOOLGENERATOR<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00161 generateKeyPool(node_id_t id, KeyPool pool){ 00162 00163 00164 00165 00166 00167 //begin key pool generation 00168 uint8_t curTaKey[KEY_LENGTH] = {0}; 00169 uint8_t curHashedKey[KEY_LENGTH] = {0}; 00170 00171 00172 00173 00174 00175 //self public key 00176 createHarpsPublicKey((uint16_t)id, publicKey); 00177 00178 srand(TA_SECRET_RANDOM_VALUE); 00179 00180 00181 00182 for(uint16_t i = 0; i < taPoolSize; i++){ 00183 00184 00185 //generate TA Key 00186 for(uint8_t j = 0; j < KEY_LENGTH; j++){ 00187 00188 curTaKey[j] = (uint8_t)rand(MAX_BYTE_VALUE); 00189 #ifdef DEBUG_L2 00190 debug_->debug("TAKey (%d) %d ",j, curTaKey[j]); 00191 #endif 00192 00193 } 00194 //lookup if current TA key exists in the nodes public key 00195 for(uint16_t j = 0; j < keyPoolSize; j++){ 00196 if(publicKey[j].keyId == i){ 00197 00198 if(publicKey[j].hashDepth > 0){ 00199 memcpy(curHashedKey, curTaKey, KEY_LENGTH); 00200 for(uint16_t k = 0; k < publicKey[j].hashDepth; k++){ 00201 uint8_t tmp[KEY_LENGTH] = {0x00, 0x00, 0x00,0x00, 0x00,0x00,0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00202 uint8_t hashKey[KEY_LENGTH] = {0x85,0x98,0x17,0x00,0xfd,0x9d,0xaa,0x11,0x97,0x41,0xa7,0x5b,0xc0,0x82,0x55,0x93}; 00203 //SHA1::hmac_sha1(input,input_len,Key,Key_len,output); 00204 //before refactoring 00205 //SHA1::hmac_sha1(curHashedKey,KEY_LENGTH,hashKey,KEY_LENGTH,tmp); 00206 //after refactoring 00207 00208 HarpsUtils::hash(curHashedKey,KEY_LENGTH,hashKey,KEY_LENGTH,tmp); 00209 00210 memcpy(curHashedKey, tmp, KEY_LENGTH); 00211 } 00212 } 00213 else{ 00214 memcpy(curHashedKey, curTaKey, KEY_LENGTH); 00215 } 00216 00217 //write the hashed key to the flash at the position given by the order of the 00218 //nodes public key (the keypool address space starts at adress KEYPOOL_ADRESS, 00219 //j is the keys position in the public key) 00220 00221 00222 struct HarpsUtils::HarpsKey key; 00223 00224 memcpy(key.hashedKey, curHashedKey,KEY_LENGTH); 00225 00226 00227 key.pubKey = publicKey[j]; 00228 00229 00230 00231 ((struct HarpsUtils::HarpsKey*)pool)[j] = (struct HarpsUtils::HarpsKey)key; 00232 00233 00234 00235 00236 break; 00237 } 00238 00239 00240 } 00241 } 00242 //End of keypool generation 00243 00244 00245 return 1; 00246 00247 } 00248 00249 // ----------------------------------------------------------------------- 00250 00251 // ----------------------------------------------------------------------- 00252 /* 00253 * @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 00254 * @param nodeId the communication partner ID 00255 * @param pubKey out array contains tuples of public keys of the communication partner (keyID, hashdepth) 00256 */ 00257 00258 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00259 void 00260 HARPSKEYPOOLGENERATOR<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00261 createHarpsPublicKey(uint16_t commPartnerId, struct HarpsUtils::HarpsPublicKey* commPartnerPubKey) { 00262 00263 //1. IDs 00264 00265 int shift = 0xfe45; 00266 srand((uint16_t)(commPartnerId + shift)); 00267 00268 for(uint16_t i = 0; i < keyPoolSize; i++) { 00269 //commPartnerPubKey[i].keyId = (uint16_t)HARPSUTILS::rand((uint16_t)taPoolSize,&randomValue_); 00270 //commPartnerPubKey[i].hashDepth = (uint8_t)HARPSUTILS::rand(maxHashDepth,&randomValue_); 00271 commPartnerPubKey[i].keyId = (uint16_t)HarpsUtils::rand((uint16_t)taPoolSize,&randomValue1_,&randomValue2_); 00272 commPartnerPubKey[i].hashDepth = (uint8_t)HarpsUtils::rand(maxHashDepth,&randomValue1_,&randomValue2_); 00273 //check if the key id already exists in the nodes public key 00274 for(uint16_t j = 0; j < i; j++) { 00275 //if key id already exists then skip it 00276 if(commPartnerPubKey[i].keyId == commPartnerPubKey[j].keyId) { 00277 i--; 00278 break; 00279 } 00280 } 00281 } 00282 00283 00284 00285 //Sorting 00286 00287 HarpsUtils::quicksort((struct HarpsUtils::HarpsPublicKey*)commPartnerPubKey, (int16_t)0, (int16_t)keyPoolSize - 1); 00288 00289 00290 00291 #ifdef DEBUG_L1 00292 debug_->debug("My public key %x",commPartnerId); 00293 for(uint16_t i = 0 ; i< keyPoolSize; i++) 00294 debug_->debug("pk[%d].id=%d - pk[%d].depth=%d",i,commPartnerPubKey[i].keyId,i,commPartnerPubKey[i].hashDepth); 00295 #endif 00296 00297 00298 } 00299 00300 // ----------------------------------------------------------------------- 00301 00302 00303 // ----------------------------------------------------------------------- 00304 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00305 void 00306 HARPSKEYPOOLGENERATOR<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00307 srand(uint32_t new_seed) { 00308 randomValue_ = new_seed; 00309 randomValue1_ = new_seed-3; 00310 randomValue2_ = new_seed+7; 00311 } 00312 00313 00314 00315 00316 // ----------------------------------------------------------------------- 00317 template<typename OsModel_P,typename Radio_P, typename Debug_P,typename KeyPool_P, typename HashAlgo_P> 00318 uint32_t 00319 HARPSKEYPOOLGENERATOR<OsModel_P, Radio_P, Debug_P, KeyPool_P, HashAlgo_P>:: 00320 rand(uint32_t upper_bound) { 00321 /* Returns a pseudo-random-number between 0 and upper_bound-1, 00322 * Using a linear congruential generator: 00323 * 00324 * X(i+1) = ((a*X(i))+c) mod m 00325 * 00326 * Common values (quote from Wikipedia, http://en.wikipedia.org/wiki/Linear_congruential_generator): 00327 * a = 1664525, c = 1013904223, m=2^32 (Numerical Recipes) 00328 * a = 22695477, c = 1, m=2^32 (Borland C/C++) 00329 * a = 69069, c = 5, m=2^32 (GNU Compiler Collection) 00330 * a = 1103515245, c = 12345, m=2^32 (ANSI C) 00331 * a = 134775813, c = 1, m=2^32 (Borland Delphi) 00332 * a = 214013, c = 2531011, m=2^32 (Microsoft Visual/Quick C/C++) 00333 * 00334 */ 00335 00336 uint32_t* r = &randomValue_; 00337 00338 uint8_t input [KEY_LENGTH] = {0}; 00339 uint8_t output [KEY_LENGTH] = {0}; 00340 00341 for(uint8_t i = 0 ; i<KEY_LENGTH; i+=4){ 00342 00343 memcpy(input+i,r,4); 00344 00345 00346 } 00347 00348 00349 00350 uint8_t hashKey[KEY_LENGTH] = {0x8d, 0x84, 0xac,0x4e, 0x5a,0x39,0x0c,0xa9, 0x10, 0x6d, 0x74, 0x08, 0x6e, 0xda, 0x0b}; 00351 //before refactoring 00352 //SHA1::hmac_sha1(input,input_len,Key,Key_len,output); 00353 //SHA1::hmac_sha1(input,KEY_LENGTH,hashKey,KEY_LENGTH,output); 00354 //after refactoring 00355 HarpsUtils::hash(input,KEY_LENGTH,hashKey,KEY_LENGTH,output); 00356 memcpy(r,output,4); 00357 randomValue_ = *r; 00358 randomValue_ = ((1664525 * randomValue_) + 1013904223 ); // mod m mit m= 2^32 00359 00360 return (randomValue_ % upper_bound); 00361 } 00362 00363 // ----------------------------------------------------------------------- 00364 00365 00366 } 00367 #endif 00368