This is a port of cyaSSL 2.7.0.

Dependents:   CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet

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-2013 wolfSSL Inc.
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 #include <cyassl/ctaocrypt/settings.h>
00027 
00028 #ifndef NO_DH
00029 
00030 #include <cyassl/ctaocrypt/dh.h>
00031 #include <cyassl/ctaocrypt/ctaoerror2.h>
00032 
00033 #ifndef USER_MATH_LIB
00034     #include <math.h>
00035     #define XPOW(x,y) pow((x),(y))
00036     #define XLOG(x)   log((x))
00037 #else
00038     /* user's own math lib */
00039 #endif
00040 
00041 
00042 #ifndef min
00043 
00044     static INLINE word32 min(word32 a, word32 b)
00045     {
00046         return a > b ? b : a;
00047     }
00048 
00049 #endif /* min */
00050 
00051 
00052 void InitDhKey(DhKey* key)
00053 {
00054     (void)key;
00055 /* TomsFastMath doesn't use memory allocation */
00056 #ifndef USE_FAST_MATH
00057     key->p.dp = 0;
00058     key->g.dp = 0;
00059 #endif
00060 }
00061 
00062 
00063 void FreeDhKey(DhKey* key)
00064 {
00065     (void)key;
00066 /* TomsFastMath doesn't use memory allocation */
00067 #ifndef USE_FAST_MATH
00068     mp_clear(&key->p);
00069     mp_clear(&key->g);
00070 #endif
00071 }
00072 
00073 
00074 static word32 DiscreteLogWorkFactor(word32 n)
00075 {
00076     /* assuming discrete log takes about the same time as factoring */
00077     if (n<5)
00078         return 0;
00079     else
00080         return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
00081                 XPOW(XLOG((double)n), 2.0/3.0) - 5);
00082 }
00083 
00084 
00085 static void GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz)
00086 {
00087     word32 sz = mp_unsigned_bin_size(&key->p);
00088     sz = min(sz, 2 * DiscreteLogWorkFactor(sz * CYASSL_BIT_SIZE) /
00089                                            CYASSL_BIT_SIZE + 1);
00090     RNG_GenerateBlock(rng, priv, sz);
00091     priv[0] |= 0x0C;
00092 
00093     *privSz = sz;
00094 }
00095 
00096 
00097 static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz,
00098                           byte* pub, word32* pubSz)
00099 {
00100     int ret = 0;
00101 
00102     mp_int x; 
00103     mp_int y;
00104 
00105     if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
00106         return MP_INIT_E;
00107 
00108     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
00109         ret = MP_READ_E;
00110 
00111     if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
00112         ret = MP_EXPTMOD_E;
00113 
00114     if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
00115         ret = MP_TO_E;
00116 
00117     if (ret == 0)
00118         *pubSz = mp_unsigned_bin_size(&y);
00119 
00120     mp_clear(&y);
00121     mp_clear(&x);
00122 
00123     return ret;
00124 }
00125 
00126 
00127 int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz,
00128                       byte* pub, word32* pubSz)
00129 {
00130     GeneratePrivate(key, rng, priv, privSz);
00131     return GeneratePublic(key, priv, *privSz, pub, pubSz);
00132 
00133 }
00134 
00135 int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
00136             word32 privSz, const byte* otherPub, word32 pubSz)
00137 {
00138     int ret = 0;
00139 
00140     mp_int x; 
00141     mp_int y;
00142     mp_int z;
00143 
00144     if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
00145         return MP_INIT_E;
00146 
00147     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
00148         ret = MP_READ_E;
00149 
00150     if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
00151         ret = MP_READ_E;
00152 
00153     if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
00154         ret = MP_EXPTMOD_E;
00155 
00156     if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
00157         ret = MP_TO_E;
00158 
00159     if (ret == 0)
00160         *agreeSz = mp_unsigned_bin_size(&z);
00161 
00162     mp_clear(&z);
00163     mp_clear(&y);
00164     mp_clear(&x);
00165 
00166     return ret;
00167 }
00168 
00169 
00170 #endif /* NO_DH */
00171