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_CRYPTO_ECIES_H__ 00021 #define __ALGORITHMS_CRYPTO_ECIES_H__ 00022 00023 #define MACLEN 20 00024 #define MAXMSGLEN 54 00025 00026 #include "algorithms/crypto/eccf2m.h" 00027 #include "algorithms/crypto/sha1.h" 00028 #include <string.h> 00029 00030 namespace wiselib 00031 { 00042 template<typename OsModel_P> 00043 class ECIES 00044 { 00045 public: 00046 typedef OsModel_P OsModel; 00047 00050 ECIES(); 00051 ~ECIES(); 00053 00056 void enable( void ); 00057 void disable( void ); 00059 00063 void encrypt(uint8_t * input, uint8_t * output, int8_t length, PubKey KeyA ); 00064 int8_t decrypt(uint8_t * input, uint8_t * output, int8_t length, PrivKey KeyB); 00065 00066 //initialize curve parameters 00067 void key_setup(); 00068 00069 private: 00070 00071 }; 00072 00073 // ----------------------------------------------------------------------- 00074 template<typename OsModel_P> 00075 ECIES<OsModel_P>:: 00076 ECIES() 00077 {} 00078 // ----------------------------------------------------------------------- 00079 template<typename OsModel_P> 00080 ECIES<OsModel_P>:: 00081 ~ECIES() 00082 {} 00083 // ----------------------------------------------------------------------- 00084 template<typename OsModel_P> 00085 void 00086 ECIES<OsModel_P>:: 00087 enable( void ) 00088 { 00089 key_setup(); 00090 } 00091 // ----------------------------------------------------------------------- 00092 template<typename OsModel_P> 00093 void 00094 ECIES<OsModel_P>:: 00095 disable( void ) 00096 { 00097 } 00098 //---------------------------------------------------------------------------- 00099 template<typename OsModel_P> 00100 void 00101 ECIES<OsModel_P>:: 00102 encrypt(uint8_t * input, uint8_t * output, int8_t length, PubKey KeyA ) 00103 { 00104 //initialize keys 00105 PubKey pubKeyA; 00106 PrivKey privKeyA; 00107 Point secretA; 00108 ECC::b_clear(privKeyA.s); 00109 ECC::p_clear(&pubKeyA.W); 00110 ECC::p_clear(&secretA); 00111 00112 // K used for creating a key of length message length 00113 uint8_t K[MAXMSGLEN + MACLEN]; 00114 for(int8_t m=0; m < MAXMSGLEN + MACLEN; m++) 00115 { 00116 K[m]=0; 00117 } 00118 00119 //generate private key 00120 ECC::gen_private_key(privKeyA.s,31); 00121 00122 //generate public key 00123 ECC::gen_public_key(privKeyA.s,&pubKeyA.W); 00124 00125 //gen shared secret by multiplying with other member's public key 00126 ECC::gen_shared_secret(privKeyA.s, &KeyA.W, &secretA); 00127 00128 //place pubKeyA to output for the other member to receive 00129 for(int8_t i=NUMWORDS/2; i<NUMWORDS;i++) 00130 { 00131 output[i-NUMWORDS/2]= pubKeyA.W.x.val[i]; 00132 output[i]= pubKeyA.W.y.val[i]; 00133 } 00134 00135 //use KDF to generate K of length message + hash 00136 //keylen = length, maclen = 20 00137 SHA1::KDF(K, length + MACLEN, secretA.x.val); 00138 00139 //encrypt the byte block using one time padding 00140 for (int16_t i=0; i<length; i++) 00141 { 00142 output[i+NUMWORDS] = input[i] ^ K[i]; 00143 } 00144 00145 //hash the public key and the encrypted value with SHA-1 and place 00146 //a message authentication code (MAC) on the end of output (20 bytes) 00147 SHA1::hmac_sha1(output, NUMWORDS+length, K+length, MACLEN, output + NUMWORDS + length); 00148 } 00149 //--------------------------------------------------------------------------- 00150 template<typename OsModel_P> 00151 int8_t 00152 ECIES<OsModel_P>:: 00153 decrypt(uint8_t * input, uint8_t * output, int8_t length, PrivKey KeyB) 00154 { 00155 //init keys 00156 PubKey PubKeyRec; 00157 ECC::p_clear(&PubKeyRec.W); 00158 Point secretB; 00159 ECC::p_clear(&secretB); 00160 00161 // K used for creating a key of length message length 00162 uint8_t K[MAXMSGLEN + MACLEN]; 00163 for(int8_t m=0; m < MAXMSGLEN + MACLEN; m++) 00164 { 00165 K[m]=0; 00166 } 00167 00168 //get the received public key from the encrypted message 00169 for(int8_t i=NUMWORDS/2; i<NUMWORDS; i++) 00170 { 00171 PubKeyRec.W.x.val[i]= input[i-NUMWORDS/2]; 00172 PubKeyRec.W.y.val[i]= input[i]; 00173 } 00174 00175 //generate the shared secret by multiplying with other member's public key 00176 ECC::gen_shared_secret( KeyB.s, &PubKeyRec.W, &secretB); 00177 00178 //used for mac verification 00179 uint8_t mac[20]; 00180 for(int8_t n=0;n<20;n++) 00181 { 00182 mac[n]=0; 00183 } 00184 00185 //use KDF to generate K of length message + hash 00186 //keylen = length, maclen = 20 00187 SHA1::KDF(K, length + MACLEN, secretB.x.val); 00188 00189 //hash the received data with the key and check 00190 //if they are the same with the hash of the message 00191 SHA1::hmac_sha1(input, NUMWORDS+length, K+length, MACLEN, mac); 00192 00193 //mac verification 00194 for (int16_t i=0; i<20; i++) 00195 { 00196 if (mac[i] != input[NUMWORDS + length + i]) 00197 return 6; 00198 } 00199 00200 //if mac ok --> decrypt using one time padding 00201 for(int16_t j=0; j<length; j++) 00202 { 00203 output[j] = input[j+NUMWORDS] ^ K[j]; 00204 } 00205 00206 return length; 00207 } 00208 00209 //------------------------------------------------------------------------------ 00210 template<typename OsModel_P> 00211 void 00212 ECIES<OsModel_P>:: 00213 key_setup() 00214 { 00215 //initialize curve parameters 00216 ECC::init(); 00217 } 00218 } 00219 #endif