Wiselib
wiselib.testing/algorithms/crypto/eciesf2m.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_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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines