]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/CyaSSL/ctaocrypt/src/dh.c
Update CyaSSL to latest version.
[freertos] / FreeRTOS-Plus / Source / CyaSSL / ctaocrypt / src / dh.c
1 /* dh.c
2  *
3  * Copyright (C) 2006-2014 wolfSSL Inc.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #include <cyassl/ctaocrypt/settings.h>
27
28 #ifndef NO_DH
29
30 #include <cyassl/ctaocrypt/dh.h>
31 #include <cyassl/ctaocrypt/error-crypt.h>
32
33 #ifndef USER_MATH_LIB
34     #include <math.h>
35     #define XPOW(x,y) pow((x),(y))
36     #define XLOG(x)   log((x))
37 #else
38     /* user's own math lib */
39 #endif
40
41
42 #ifndef min
43
44     static INLINE word32 min(word32 a, word32 b)
45     {
46         return a > b ? b : a;
47     }
48
49 #endif /* min */
50
51
52 void InitDhKey(DhKey* key)
53 {
54     (void)key;
55 /* TomsFastMath doesn't use memory allocation */
56 #ifndef USE_FAST_MATH
57     key->p.dp = 0;
58     key->g.dp = 0;
59 #endif
60 }
61
62
63 void FreeDhKey(DhKey* key)
64 {
65     (void)key;
66 /* TomsFastMath doesn't use memory allocation */
67 #ifndef USE_FAST_MATH
68     mp_clear(&key->p);
69     mp_clear(&key->g);
70 #endif
71 }
72
73
74 static word32 DiscreteLogWorkFactor(word32 n)
75 {
76     /* assuming discrete log takes about the same time as factoring */
77     if (n<5)
78         return 0;
79     else
80         return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
81                 XPOW(XLOG((double)n), 2.0/3.0) - 5);
82 }
83
84
85 static int GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz)
86 {
87     int ret;
88     word32 sz = mp_unsigned_bin_size(&key->p);
89     sz = min(sz, 2 * DiscreteLogWorkFactor(sz * CYASSL_BIT_SIZE) /
90                                            CYASSL_BIT_SIZE + 1);
91
92     ret = RNG_GenerateBlock(rng, priv, sz);
93     if (ret != 0)
94         return ret;
95
96     priv[0] |= 0x0C;
97
98     *privSz = sz;
99
100     return 0;
101 }
102
103
104 static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz,
105                           byte* pub, word32* pubSz)
106 {
107     int ret = 0;
108
109     mp_int x; 
110     mp_int y;
111
112     if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
113         return MP_INIT_E;
114
115     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
116         ret = MP_READ_E;
117
118     if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
119         ret = MP_EXPTMOD_E;
120
121     if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
122         ret = MP_TO_E;
123
124     if (ret == 0)
125         *pubSz = mp_unsigned_bin_size(&y);
126
127     mp_clear(&y);
128     mp_clear(&x);
129
130     return ret;
131 }
132
133
134 int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz,
135                       byte* pub, word32* pubSz)
136 {
137     int ret = GeneratePrivate(key, rng, priv, privSz);
138
139     return (ret != 0) ? ret : GeneratePublic(key, priv, *privSz, pub, pubSz);
140 }
141
142 int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
143             word32 privSz, const byte* otherPub, word32 pubSz)
144 {
145     int ret = 0;
146
147     mp_int x; 
148     mp_int y;
149     mp_int z;
150
151     if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
152         return MP_INIT_E;
153
154     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
155         ret = MP_READ_E;
156
157     if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
158         ret = MP_READ_E;
159
160     if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
161         ret = MP_EXPTMOD_E;
162
163     if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
164         ret = MP_TO_E;
165
166     if (ret == 0)
167         *agreeSz = mp_unsigned_bin_size(&z);
168
169     mp_clear(&z);
170     mp_clear(&y);
171     mp_clear(&x);
172
173     return ret;
174 }
175
176
177 #endif /* NO_DH */
178