]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/CyaSSL/ctaocrypt/src/dh.c
e7c6faa035761a150e9b79d42e0aa05880f3a652
[freertos] / FreeRTOS-Plus / CyaSSL / ctaocrypt / src / dh.c
1 /* dh.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #ifndef NO_DH
27
28 #include <cyassl/ctaocrypt/dh.h>
29 #include <cyassl/ctaocrypt/error.h>
30
31 #ifndef USER_MATH_LIB
32     #include <math.h>
33     #define XPOW(x,y) pow((x),(y))
34     #define XLOG(x)   log((x))
35 #else
36     /* user's own math lib */
37 #endif
38
39
40 #ifndef min
41
42     static INLINE word32 min(word32 a, word32 b)
43     {
44         return a > b ? b : a;
45     }
46
47 #endif /* min */
48
49
50 void InitDhKey(DhKey* key)
51 {
52     (void)key;
53 /* TomsFastMath doesn't use memory allocation */
54 #ifndef USE_FAST_MATH
55     key->p.dp = 0;
56     key->g.dp = 0;
57 #endif
58 }
59
60
61 void FreeDhKey(DhKey* key)
62 {
63     (void)key;
64 /* TomsFastMath doesn't use memory allocation */
65 #ifndef USE_FAST_MATH
66     mp_clear(&key->p);
67     mp_clear(&key->g);
68 #endif
69 }
70
71
72 static word32 DiscreteLogWorkFactor(word32 n)
73 {
74     /* assuming discrete log takes about the same time as factoring */
75     if (n<5)
76         return 0;
77     else
78         return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
79                 XPOW(XLOG((double)n), 2.0/3.0) - 5);
80 }
81
82
83 static void GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz)
84 {
85     word32 sz = mp_unsigned_bin_size(&key->p);
86     sz = min(sz, 2 * DiscreteLogWorkFactor(sz * BIT_SIZE) / BIT_SIZE + 1);
87
88     RNG_GenerateBlock(rng, priv, sz);
89     priv[0] |= 0x0C;
90
91     *privSz = sz;
92 }
93
94
95 static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz,
96                           byte* pub, word32* pubSz)
97 {
98     int ret = 0;
99
100     mp_int x; 
101     mp_int y;
102
103     if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
104         return MP_INIT_E;
105
106     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
107         ret = MP_READ_E;
108
109     if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
110         ret = MP_EXPTMOD_E;
111
112     if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
113         ret = MP_TO_E;
114
115     if (ret == 0)
116         *pubSz = mp_unsigned_bin_size(&y);
117
118     mp_clear(&y);
119     mp_clear(&x);
120
121     return ret;
122 }
123
124
125 int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz,
126                       byte* pub, word32* pubSz)
127 {
128     GeneratePrivate(key, rng, priv, privSz);
129     return GeneratePublic(key, priv, *privSz, pub, pubSz);
130
131 }
132
133 int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
134             word32 privSz, const byte* otherPub, word32 pubSz)
135 {
136     int ret = 0;
137
138     mp_int x; 
139     mp_int y;
140     mp_int z;
141
142     if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
143         return MP_INIT_E;
144
145     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
146         ret = MP_READ_E;
147
148     if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
149         ret = MP_READ_E;
150
151     if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
152         ret = MP_EXPTMOD_E;
153
154     if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
155         ret = MP_TO_E;
156
157     if (ret == 0)
158         *agreeSz = mp_unsigned_bin_size(&z);
159
160     mp_clear(&z);
161     mp_clear(&y);
162     mp_clear(&x);
163
164     return ret;
165 }
166
167
168 #endif /* NO_DH */
169