1 /*
2 
3   groups.c
4 
5   Author: Pekka Riikonen <priikone@silcnet.org>
6 
7   Copyright (C) 2000 - 2006 Pekka Riikonen
8 
9   The contents of this file are subject to one of the Licenses specified
10   in the COPYING file;  You may not use this file except in compliance
11   with the License.
12 
13   The software distributed under the License is distributed on an "AS IS"
14   basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY
15   KIND, either expressed or implied.  See the COPYING file for more
16   information.
17 
18 */
19 /* $Id$ */
20 
21 #include "silc.h"
22 #include "groups_internal.h"
23 
24 /* Fixed and public Diffie Hellman Groups defined by the SKE
25    protocol. These are equivalent to the OAKLEY Key Determination
26    protocol groups. */
27 const struct SilcSKEDiffieHellmanGroupDefStruct silc_ske_groups[] =
28 {
29   /* 1536 bits modulus (Optional group) (RFC 3526). */
30   { 2, "diffie-hellman-group2",
31 
32     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
33     "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
34     "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
35     "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
36     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
37     "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
38     "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
39     "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF",
40 
41     "7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68"
42     "948127044533E63A0105DF531D89CD9128A5043CC71A026E"
43     "F7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122"
44     "F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6"
45     "F71C35FDAD44CFD2D74F9208BE258FF324943328F6722D9E"
46     "E1003E5C50B1DF82CC6D241B0E2AE9CD348B1FD47E9267AF"
47     "C1B2AE91EE51D6CB0E3179AB1042A95DCF6A9483B84B4B36"
48     "B3861AA7255E4C0278BA36046511B993FFFFFFFFFFFFFFFF",
49     "2" },
50 
51   /* 1024 bits modulus (Mandatory group) (RFC 2412). */
52   { 1, "diffie-hellman-group1",
53 
54     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
55     "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
56     "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
57     "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
58     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
59     "FFFFFFFFFFFFFFFF",
60 
61     "7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68"
62     "948127044533E63A0105DF531D89CD9128A5043CC71A026E"
63     "F7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122"
64     "F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6"
65     "F71C35FDAD44CFD2D74F9208BE258FF324943328F67329C0"
66     "FFFFFFFFFFFFFFFF",
67     "2" },
68 
69   { 0, NULL, NULL, NULL }
70 };
71 
72 /* Returns Diffie Hellman group by group number */
73 
silc_ske_group_get_by_number(int number,SilcSKEDiffieHellmanGroup * ret)74 SilcSKEStatus silc_ske_group_get_by_number(int number,
75 					   SilcSKEDiffieHellmanGroup *ret)
76 {
77   int i;
78   SilcSKEDiffieHellmanGroup group;
79 
80   for (i = 0; silc_ske_groups[i].name; i++) {
81     if (silc_ske_groups[i].number == number)
82       break;
83   }
84 
85   if (silc_ske_groups[i].name == NULL) {
86     SILC_LOG_ERROR(("Unsupported Diffie-Hellman group number %d", number));
87     return SILC_SKE_STATUS_UNKNOWN_GROUP;
88   }
89 
90   /* Return the group */
91   if (ret) {
92     group = silc_calloc(1, sizeof(*group));
93     group->number = number;
94     group->name = silc_ske_groups[i].name;
95     silc_mp_init(&group->group);
96     silc_mp_init(&group->group_order);
97     silc_mp_init(&group->generator);
98     silc_mp_set_str(&group->group, silc_ske_groups[i].group, 16);
99     silc_mp_set_str(&group->group_order, silc_ske_groups[i].group_order, 16);
100     silc_mp_set_str(&group->generator, silc_ske_groups[i].generator, 16);
101 
102     *ret = group;
103   }
104 
105   return SILC_SKE_STATUS_OK;
106 }
107 
108 /* Returns Diffie Hellman group by name */
109 
silc_ske_group_get_by_name(const char * name,SilcSKEDiffieHellmanGroup * ret)110 SilcSKEStatus silc_ske_group_get_by_name(const char *name,
111 					 SilcSKEDiffieHellmanGroup *ret)
112 {
113   int i;
114   SilcSKEDiffieHellmanGroup group;
115 
116   for (i = 0; silc_ske_groups[i].name; i++) {
117     if (!strcmp(silc_ske_groups[i].name, name))
118       break;
119   }
120 
121   if (silc_ske_groups[i].name == NULL) {
122     SILC_LOG_ERROR(("Unsupported Diffie-Hellman group `%s'", name));
123     return SILC_SKE_STATUS_UNKNOWN_GROUP;
124   }
125 
126   /* Return the group */
127   if (ret) {
128     group = silc_calloc(1, sizeof(*group));
129     group->number = silc_ske_groups[i].number;
130     group->name = silc_ske_groups[i].name;
131     silc_mp_init(&group->group);
132     silc_mp_init(&group->group_order);
133     silc_mp_init(&group->generator);
134     silc_mp_set_str(&group->group, silc_ske_groups[i].group, 16);
135     silc_mp_set_str(&group->group_order, silc_ske_groups[i].group_order, 16);
136     silc_mp_set_str(&group->generator, silc_ske_groups[i].generator, 16);
137 
138     *ret = group;
139   }
140 
141   return SILC_SKE_STATUS_OK;
142 }
143 
144 /* Free group */
145 
silc_ske_group_free(SilcSKEDiffieHellmanGroup group)146 void silc_ske_group_free(SilcSKEDiffieHellmanGroup group)
147 {
148   silc_mp_uninit(&group->group);
149   silc_mp_uninit(&group->group_order);
150   silc_mp_uninit(&group->generator);
151   silc_free(group);
152 }
153 
154 /* Returns comma separated list of supported groups */
155 
silc_ske_get_supported_groups(SilcUInt32 limit)156 char *silc_ske_get_supported_groups(SilcUInt32 limit)
157 {
158   char *list = NULL;
159   int i, len;
160 
161   if (!limit)
162     limit = ~0;
163 
164   len = 0;
165   for (i = 0; silc_ske_groups[i].name && i < limit; i++) {
166     len += strlen(silc_ske_groups[i].name);
167     list = silc_realloc(list, len + 1);
168 
169     memcpy(list + (len - strlen(silc_ske_groups[i].name)),
170 	   silc_ske_groups[i].name, strlen(silc_ske_groups[i].name));
171     memcpy(list + len, ",", 1);
172     len++;
173   }
174 
175   if (list)
176     list[len - 1] = 0;
177 
178   return list;
179 }
180 
181 /* Returns the number of the `group'. */
182 
silc_ske_group_get_number(SilcSKEDiffieHellmanGroup group)183 int silc_ske_group_get_number(SilcSKEDiffieHellmanGroup group)
184 {
185   return group->number;
186 }
187 
188 /* Returns the name of the `group'. */
189 
silc_ske_group_get_name(SilcSKEDiffieHellmanGroup group)190 const char *silc_ske_group_get_name(SilcSKEDiffieHellmanGroup group)
191 {
192   return group->name;
193 }
194