cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers dh.c Source File

dh.c

00001 /* dh.c
00002  *
00003  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023     #include <config.h>
00024 #endif
00025 
00026 #ifndef NO_DH
00027 
00028 #include <cyassl/ctaocrypt/dh.h>
00029 #include <cyassl/ctaocrypt/error.h>
00030 
00031 #ifndef USER_MATH_LIB
00032     #include <math.h>
00033     #define XPOW(x,y) pow((x),(y))
00034     #define XLOG(x)   log((x))
00035 #else
00036     /* user's own math lib */
00037 #endif
00038 
00039 
00040 #ifndef min
00041 
00042     static INLINE word32 min(word32 a, word32 b)
00043     {
00044         return a > b ? b : a;
00045     }
00046 
00047 #endif /* min */
00048 
00049 
00050 void InitDhKey(DhKey* key)
00051 {
00052     (void)key;
00053 /* TomsFastMath doesn't use memory allocation */
00054 #ifndef USE_FAST_MATH
00055     key->p.dp = 0;
00056     key->g.dp = 0;
00057 #endif
00058 }
00059 
00060 
00061 void FreeDhKey(DhKey* key)
00062 {
00063     (void)key;
00064 /* TomsFastMath doesn't use memory allocation */
00065 #ifndef USE_FAST_MATH
00066     mp_clear(&key->p);
00067     mp_clear(&key->g);
00068 #endif
00069 }
00070 
00071 
00072 static word32 DiscreteLogWorkFactor(word32 n)
00073 {
00074     /* assuming discrete log takes about the same time as factoring */
00075     if (n<5)
00076         return 0;
00077     else
00078         return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
00079                 XPOW(XLOG((double)n), 2.0/3.0) - 5);
00080 }
00081 
00082 
00083 static void GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz)
00084 {
00085     word32 sz = mp_unsigned_bin_size(&key->p);
00086     sz = min(sz, 2 * DiscreteLogWorkFactor(sz * BIT_SIZE) / BIT_SIZE + 1);
00087 
00088     RNG_GenerateBlock(rng, priv, sz);
00089     priv[0] |= 0x0C;
00090 
00091     *privSz = sz;
00092 }
00093 
00094 
00095 static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz,
00096                           byte* pub, word32* pubSz)
00097 {
00098     int ret = 0;
00099 
00100     mp_int x; 
00101     mp_int y;
00102 
00103     if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
00104         return MP_INIT_E;
00105 
00106     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
00107         ret = MP_READ_E;
00108 
00109     if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
00110         ret = MP_EXPTMOD_E;
00111 
00112     if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
00113         ret = MP_TO_E;
00114 
00115     if (ret == 0)
00116         *pubSz = mp_unsigned_bin_size(&y);
00117 
00118     mp_clear(&y);
00119     mp_clear(&x);
00120 
00121     return ret;
00122 }
00123 
00124 
00125 int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz,
00126                       byte* pub, word32* pubSz)
00127 {
00128     GeneratePrivate(key, rng, priv, privSz);
00129     return GeneratePublic(key, priv, *privSz, pub, pubSz);
00130 
00131 }
00132 
00133 int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
00134             word32 privSz, const byte* otherPub, word32 pubSz)
00135 {
00136     int ret = 0;
00137 
00138     mp_int x; 
00139     mp_int y;
00140     mp_int z;
00141 
00142     if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
00143         return MP_INIT_E;
00144 
00145     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
00146         ret = MP_READ_E;
00147 
00148     if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
00149         ret = MP_READ_E;
00150 
00151     if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
00152         ret = MP_EXPTMOD_E;
00153 
00154     if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
00155         ret = MP_TO_E;
00156 
00157     if (ret == 0)
00158         *agreeSz = mp_unsigned_bin_size(&z);
00159 
00160     mp_clear(&z);
00161     mp_clear(&y);
00162     mp_clear(&x);
00163 
00164     return ret;
00165 }
00166 
00167 
00168 #endif /* NO_DH */
00169