Wiselib
wiselib.testing/algorithms/crypto/eciesfp.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_ECIESFP_H__
00021 #define __ALGORITHMS_CRYPTO_ECIESFP_H__
00022 
00023 //hash length (case of sha-1 hash)
00024 #define HMAC_LEN 20
00025 
00026 //max msg length according to radio
00027 //maximum payload size 116 bytes e.g for iSense radio
00028 
00029 //case of 128-bit elliptic curve (34 + msg + HMAC_LEN)
00030 //#define MAX_M_LEN 62
00031 
00032 //case of 160-bit elliptic curve (42 + msg + HMAC_LEN)
00033 #define MAX_M_LEN 54
00034 
00035 //case of 192-bit elliptic curve (50 + msg + HMAC_LEN)
00036 //#define MAX_M_LEN 46
00037 
00038 #include "algorithms/crypto/eccfp.h"
00039 #include "algorithms/crypto/pmp.h"
00040 #include "algorithms/crypto/sha1.h"
00041 #include <string.h>
00042 
00043 namespace wiselib
00044 {
00055    template<typename OsModel_P>
00056    class ECIESFP
00057    {
00058    public:
00059       typedef OsModel_P OsModel;
00060 
00063       ECIESFP();
00064       ~ECIESFP();
00066 
00069       void enable( void );
00070       void disable( void );
00072 
00076       int8_t encrypt(uint8_t * input, uint8_t * output, int8_t msg_length, Point *KeyA );
00077       int8_t decrypt(uint8_t * input, uint8_t * output, int8_t msg_length, NN_DIGIT *KeyB);
00078 
00079       //initialize parameter for private key generation
00080       void key_setup(uint8_t seed);
00081 
00082    private:
00083       //objects for necessary classes
00084       ECCFP eccfp;
00085       PMP pmp;
00086       uint8_t seed1;
00087    };
00088 
00089    // -----------------------------------------------------------------------
00090    template<typename OsModel_P>
00091    ECIESFP<OsModel_P>::
00092    ECIESFP()
00093    {}
00094    // -----------------------------------------------------------------------
00095    template<typename OsModel_P>
00096    ECIESFP<OsModel_P>::
00097    ~ECIESFP()
00098    {}
00099    // -----------------------------------------------------------------------
00100    template<typename OsModel_P>
00101    void
00102    ECIESFP<OsModel_P>::
00103    enable( void )
00104    {
00105    }
00106    // -----------------------------------------------------------------------
00107    template<typename OsModel_P>
00108    void
00109    ECIESFP<OsModel_P>::
00110    disable( void )
00111    {
00112    }
00113    //----------------------------------------------------------------------------
00114    template<typename OsModel_P>
00115    int8_t
00116    ECIESFP<OsModel_P>::
00117    encrypt(uint8_t * input, uint8_t * output, int8_t msg_length, Point *KeyA )
00118    {
00119       NN_DIGIT k[NUMWORDS];
00120       uint8_t z[KEYDIGITS*NN_DIGIT_LEN +1];
00121 
00122       //clear points
00123       Point R, P;
00124       eccfp.p_clear(&P);
00125       eccfp.p_clear(&R);
00126 
00127       int8_t octet_len;
00128       uint8_t K[MAX_M_LEN + HMAC_LEN];
00129       int8_t i;
00130 
00131       //generate private and public key
00132       eccfp.gen_private_key(k, seed1);
00133       eccfp.gen_public_key(&R, k);
00134 
00135       //2. convert R to octet string
00136       octet_len = eccfp.point2octet(output, 2*(KEYDIGITS*NN_DIGIT_LEN + 1), &R, FALSE) + 1;
00137 
00138       //3. derive shared secret z=P.x
00139       eccfp.c_mul(&P, KeyA, k);
00140 
00141       if (eccfp.p_iszero(&P))
00142          return -1;
00143 
00144       //4. convert z= P.x to octet string Z
00145       pmp.Encode(z, KEYDIGITS * NN_DIGIT_LEN +1, P.x, NUMWORDS);
00146 
00147       //5. use KDF to generate K of length enckeylen + mackeylen octets from z
00148       //enckeylen = message length, mackeylen = 20
00149       SHA1::KDF(K, msg_length + HMAC_LEN, z);
00150 
00151       //6. encrypt the message
00152       for (i=0; i<msg_length; i++)
00153       {
00154          output[octet_len+i] = input[i] ^ K[i];
00155       }
00156 
00157       //7. generate mac D on the encrypted data + key
00158       SHA1::hmac_sha1(output + octet_len, msg_length, K + msg_length, HMAC_LEN, output + octet_len + msg_length);
00159 
00160       //8. output C = R||EM||D
00161       return (octet_len + msg_length + HMAC_LEN);
00162    }
00163 
00164 //---------------------------------------------------------------------------
00165    template<typename OsModel_P>
00166    int8_t
00167    ECIESFP<OsModel_P>::
00168    decrypt(uint8_t * input, uint8_t * output, int8_t msg_length, NN_DIGIT *KeyB)
00169    {
00170       //total length
00171       int8_t LEN = 2*(KEYDIGITS * NN_DIGIT_LEN +1) + msg_length + HMAC_LEN;
00172 
00173       uint8_t z[KEYDIGITS*NN_DIGIT_LEN + 1];
00174 
00175       //initialize points
00176       Point R, P;
00177       eccfp.p_clear(&P);
00178       eccfp.p_clear(&R);
00179 
00180       int8_t octet_len;
00181       uint8_t K[MAX_M_LEN + HMAC_LEN];
00182       int8_t i;
00183       uint8_t hmac_tmp[HMAC_LEN];
00184 
00185       //1. parse R||EM||D and
00186       //2. get the point R
00187       octet_len = eccfp.octet2point(&R, input, 2*(KEYDIGITS * NN_DIGIT_LEN +1)) +1;
00188 
00189       //3. check if R is valid
00190       if (eccfp.check_point(&R) != 1)
00191          return 3;
00192 
00193       //4. use private key to generate shared secret z
00194       eccfp.c_mul(&P, &R, KeyB);
00195 
00196       if (eccfp.p_iszero(&P))
00197          return 4;
00198 
00199       //5. convert z = P.x to octet string
00200       pmp.Encode(z, KEYDIGITS * NN_DIGIT_LEN + 1, P.x, NUMWORDS);
00201 
00202       //6. use KDF to derive EK and MK
00203       SHA1::KDF(K, msg_length + HMAC_LEN, z);
00204 
00205       //7. check D first
00206       if (msg_length < LEN - HMAC_LEN - octet_len)
00207          return 5;
00208 
00209       SHA1::hmac_sha1(input + octet_len, msg_length, K + msg_length, HMAC_LEN, hmac_tmp);
00210 
00211       for (i=0; i < HMAC_LEN; i++)
00212       {
00213          if (hmac_tmp[i] != input[octet_len + msg_length + i])
00214             return 6;
00215       }
00216 
00217       //8. decrypt
00218       for(i=0; i< msg_length; i++)
00219       {
00220          output[i] = input[octet_len + i] ^ K[i];
00221       }
00222 
00223       return msg_length;
00224    }
00225 
00226 //------------------------------------------------------------------------------
00227    template<typename OsModel_P>
00228    void
00229    ECIESFP<OsModel_P>::
00230    key_setup(uint8_t seed)
00231    {
00232       //seed used for private key generation
00233       seed1 = seed;
00234    }
00235 
00236 } //end of wiselib namespace
00237 
00238 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines